Showing preview only (597K chars total). Download the full file or copy to clipboard to get everything.
Repository: aclindsa/ofxgo
Branch: master
Commit: b2d1132f5987
Files: 57
Total size: 574.2 KB
Directory structure:
gitextract_ipheoeo0/
├── .github/
│ └── workflows/
│ └── test.yml
├── LICENSE
├── README.md
├── bank.go
├── bank_test.go
├── basic_client.go
├── basic_client_test.go
├── client.go
├── cmd/
│ └── ofx/
│ ├── bankdownload.go
│ ├── banktransactions.go
│ ├── ccdownload.go
│ ├── cctransactions.go
│ ├── command.go
│ ├── detect_settings.go
│ ├── get_accounts.go
│ ├── invdownload.go
│ ├── invtransactions.go
│ ├── main.go
│ ├── profiledownload.go
│ └── util.go
├── common.go
├── common_test.go
├── constants.go
├── constants_test.go
├── creditcard.go
├── creditcard_test.go
├── discovercard_client.go
├── doc.go
├── generate_constants.py
├── go.mod
├── go.sum
├── invstmt.go
├── invstmt_test.go
├── leaf_elements.go
├── profile.go
├── profile_test.go
├── request.go
├── request_test.go
├── response.go
├── response_test.go
├── samples/
│ ├── busted_responses/
│ │ ├── bmo_v102__no_header_newline.qfx
│ │ └── wellsfargo.qfx
│ └── valid_responses/
│ ├── 401k_v203.ofx
│ ├── inv_v202.ofx
│ ├── ira_v202.ofx
│ ├── moneymrkt1_v103.ofx
│ ├── moneymrkt1_v103_TYPE1.ofx
│ └── moneymrkt1_v203.ofx
├── seclist.go
├── signon.go
├── signon_test.go
├── signup.go
├── signup_test.go
├── types.go
├── types_test.go
├── util.go
└── vanguard_client.go
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/workflows/test.yml
================================================
name: ofxgo CI Test
on: [push, pull_request]
jobs:
test:
strategy:
matrix:
go-version: [1.19.x, 1.22.x, 1.24.x]
os: [ubuntu-latest, macos-latest, windows-latest]
include:
- os: ubuntu-latest
go-version: 1.14.x
- os: windows-latest
go-version: 1.14.x
runs-on: ${{ matrix.os }}
steps:
- name: Install Go
uses: actions/setup-go@v5
with:
go-version: ${{ matrix.go-version }}
- name: Checkout code
uses: actions/checkout@v2
- name: Test
run: go test -v -covermode=count -coverprofile="profile.cov" ./...
- name: Send Coverage
uses: shogo82148/actions-goveralls@v1
with:
path-to-profile: "profile.cov"
flag-name: ${{ matrix.os }}-go-${{ matrix.go-version }}
parallel: true
# notifies that all test jobs are finished.
finish:
needs: test
runs-on: ubuntu-latest
steps:
- uses: shogo82148/actions-goveralls@v1
with:
parallel-finished: true
================================================
FILE: LICENSE
================================================
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
================================================
FILE: README.md
================================================
# OFXGo
[](https://goreportcard.com/report/github.com/aclindsa/ofxgo)
[](https://github.com/aclindsa/ofxgo/actions?query=workflow%3A%22ofxgo+CI+Test%22+branch%3Amaster)
[](https://coveralls.io/github/aclindsa/ofxgo?branch=master)
[](https://pkg.go.dev/github.com/aclindsa/ofxgo)
**OFXGo** is a library for querying OFX servers and/or parsing the responses. It
also provides an example command-line client to demonstrate the use of the
library.
## Goals
The main purpose of this project is to provide a library to make it easier to
query financial information with OFX from the comfort of Golang, without having
to marshal/unmarshal to SGML or XML. The library does _not_ intend to abstract
away all of the details of the OFX specification, which would be difficult to do
well. Instead, it exposes the OFX SGML/XML hierarchy as structs which mostly
resemble it. Its primary goal is to enable the creation of other personal
finance software in Go (as it was created to allow me to fetch OFX transactions
for my own project, [MoneyGo](https://github.com/aclindsa/moneygo)).
Because the OFX specification is rather... 'comprehensive,' it can be difficult
for those unfamiliar with it to figure out where to start. To that end, I have
created a sample command-line client which uses the library to do simple tasks
(currently it does little more than list accounts and query for balances and
transactions). My hope is that by studying its code, new users will be able to
figure out how to use the library much faster than staring at the OFX
specification (or this library's [API
documentation](https://pkg.go.dev/github.com/aclindsa/ofxgo)). The command-line client
also serves as an easy way for me to test/debug the library with actual
financial institutions, which frequently have 'quirks' in their implementations.
The command-line client can be found in the [cmd/ofx
directory](https://github.com/aclindsa/ofxgo/tree/master/cmd/ofx) of this
repository.
## Library documentation
Documentation can be found with the `go doc` tool, or at
https://pkg.go.dev/github.com/aclindsa/ofxgo
## Example Usage
The following code snippet demonstrates how to use OFXGo to query and parse
OFX code from a checking account, printing the balance and returned transactions:
```go
client := ofxgo.BasicClient{} // Accept the default Client settings
// These values are specific to your bank
var query ofxgo.Request
query.URL = "https://secu.example.com/ofx"
query.Signon.Org = ofxgo.String("SECU")
query.Signon.Fid = ofxgo.String("1234")
// Set your username/password
query.Signon.UserID = ofxgo.String("username")
query.Signon.UserPass = ofxgo.String("hunter2")
uid, _ := ofxgo.RandomUID() // Handle error in real code
query.Bank = append(query.Bank, &ofxgo.StatementRequest{
TrnUID: *uid,
BankAcctFrom: ofxgo.BankAcct{
BankID: ofxgo.String("123456789"), // Possibly your routing number
AcctID: ofxgo.String("00011122233"), // Possibly your account number
AcctType: ofxgo.AcctTypeChecking,
},
Include: true, // Include transactions (instead of only balance information)
})
response, _ := client.Request(&query) // Handle error in real code
// Was there an OFX error while processing our request?
if response.Signon.Status.Code != 0 {
meaning, _ := response.Signon.Status.CodeMeaning()
fmt.Printf("Nonzero signon status (%d: %s) with message: %s\n", response.Signon.Status.Code, meaning, response.Signon.Status.Message)
os.Exit(1)
}
if len(response.Bank) < 1 {
fmt.Println("No banking messages received")
os.Exit(1)
}
if stmt, ok := response.Bank[0].(*ofxgo.StatementResponse); ok {
fmt.Printf("Balance: %s %s (as of %s)\n", stmt.BalAmt, stmt.CurDef, stmt.DtAsOf)
fmt.Println("Transactions:")
for _, tran := range stmt.BankTranList.Transactions {
currency := stmt.CurDef
if ok, _ := tran.Currency.Valid(); ok {
currency = tran.Currency.CurSym
}
fmt.Printf("%s %-15s %-11s %s%s%s\n", tran.DtPosted, tran.TrnAmt.String()+" "+currency.String(), tran.TrnType, tran.Name, tran.Payee.Name, tran.Memo)
}
}
```
Similarly, if you have an OFX file available locally, you can parse it directly:
```go
func main() {
f, err := os.Open("./transactions.qfx")
if err != nil {
fmt.Printf("can't open file: %v\n", err)
return
}
defer f.Close()
resp, err := ofxgo.ParseResponse(f)
if err != nil {
fmt.Printf("can't parse response: %v\n", err)
return
}
// do something with resp (*ofxgo.Response)
}
```
## Requirements
OFXGo requires go >= 1.12
## Using the command-line client
To install the command-line client and test it out, you may do the following:
$ go get -v github.com/aclindsa/ofxgo/cmd/ofx && go install -v github.com/aclindsa/ofxgo/cmd/ofx
Once installed (at ~/go/bin/ofx by default, if you haven't set $GOPATH), the
command's usage should help you to use it (`./ofx --help` for a listing of the
available subcommands and their purposes, `./ofx subcommand --help` for
individual subcommand usage).
================================================
FILE: bank.go
================================================
package ofxgo
import (
"errors"
"github.com/aclindsa/xml"
)
// StatementRequest represents a request for a bank statement. It is used to
// request balances and/or transactions for checking, savings, money market,
// and line of credit accounts. See CCStatementRequest for the analog for
// credit card accounts.
type StatementRequest struct {
XMLName xml.Name `xml:"STMTTRNRQ"`
TrnUID UID `xml:"TRNUID"`
CltCookie String `xml:"CLTCOOKIE,omitempty"`
TAN String `xml:"TAN,omitempty"` // Transaction authorization number
// TODO `xml:"OFXEXTENSION,omitempty"`
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
}
// Name returns the name of the top-level transaction XML/SGML element
func (r *StatementRequest) Name() string {
return "STMTTRNRQ"
}
// Valid returns (true, nil) if this struct would be valid OFX if marshalled
// into XML/SGML
func (r *StatementRequest) Valid(version ofxVersion) (bool, error) {
if ok, err := r.TrnUID.Valid(); !ok {
return false, err
}
if r.IncludePending && version < OfxVersion220 {
return false, errors.New("StatementRequest.IncludePending invalid for OFX < 2.2")
}
if r.IncTranImg && version < OfxVersion210 {
return false, errors.New("StatementRequest.IncTranImg invalid for OFX < 2.1")
}
return r.BankAcctFrom.Valid()
}
// Type returns which message set this message belongs to (which Request
// element of type []Message it should appended to)
func (r *StatementRequest) Type() messageType {
return BankRq
}
// Payee specifies a complete billing address for a payee
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"`
}
// Valid returns (true, nil) if this struct is valid OFX
func (p Payee) Valid() (bool, error) {
if len(p.Name) == 0 {
return false, errors.New("Payee.Name empty")
} else if len(p.Addr1) == 0 {
return false, errors.New("Payee.Addr1 empty")
} else if len(p.City) == 0 {
return false, errors.New("Payee.City empty")
} else if len(p.State) == 0 {
return false, errors.New("Payee.State empty")
} else if len(p.PostalCode) == 0 {
return false, errors.New("Payee.PostalCode empty")
} else if len(p.Country) != 0 && len(p.Country) != 3 {
return false, errors.New("Payee.Country invalid length")
} else if len(p.Phone) == 0 {
return false, errors.New("Payee.Phone empty")
}
return true, nil
}
// ImageData represents the metadata surrounding a check or other image file,
// including how to retrieve the image
type ImageData struct {
XMLName xml.Name `xml:"IMAGEDATA"`
ImageType imageType `xml:"IMAGETYPE"` // One of STATEMENT, TRANSACTION, TAX
ImageRef String `xml:"IMAGEREF"` // URL or identifier, depending on IMAGEREFTYPE
ImageRefType imageRefType `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 checkSup `xml:"CHECKSUP,omitempty"` // What is contained in check images. One of FRONTONLY, BACKONLY, FRONTANDBACK
}
// Transaction represents a single banking transaction. At a minimum, it
// identifies the type of transaction (TrnType) and the date it was posted
// (DtPosted). Ideally it also provides metadata to help the user recognize
// this transaction (i.e. CheckNum, Name or Payee, Memo, etc.)
type Transaction struct {
XMLName xml.Name `xml:"STMTTRN"`
TrnType trnType `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"` // Client uses FITID to detect whether it has previously downloaded the transaction
CorrectFiTID String `xml:"CORRECTFITID,omitempty"` // Transaction ID that this transaction corrects, if present
CorrectAction correctAction `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"`
// Only one of Currency and OrigCurrency can ever be Valid() for the same transaction
Currency *Currency `xml:"CURRENCY,omitempty"` // Represents the currency of TrnAmt (instead of CURDEF in STMTRS) if Valid
OrigCurrency *Currency `xml:"ORIGCURRENCY,omitempty"` // Represents the currency TrnAmt was converted to STMTRS' CURDEF from if Valid
Inv401kSource inv401kSource `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.)
}
// Valid returns (true, nil) if this struct is valid OFX
func (t Transaction) Valid(version ofxVersion) (bool, error) {
var emptyDate Date
if !t.TrnType.Valid() || t.TrnType == TrnTypeHold {
return false, errors.New("Transaction.TrnType invalid")
} else if t.DtPosted.Equal(emptyDate) {
return false, errors.New("Transaction.DtPosted not filled")
} else if len(t.FiTID) == 0 {
return false, errors.New("Transaction.FiTID empty")
} else if len(t.CorrectFiTID) > 0 && t.CorrectAction.Valid() {
return false, errors.New("Transaction.CorrectFiTID nonempty but CorrectAction invalid")
} else if len(t.Name) > 0 && t.Payee != nil {
return false, errors.New("Only one of Transaction.Name and Payee may be specified")
}
if t.Payee != nil {
if ok, err := t.Payee.Valid(); !ok {
return false, err
}
}
if t.BankAcctTo != nil && t.CCAcctTo != nil {
return false, errors.New("Only one of Transaction.BankAcctTo and CCAcctTo may be specified")
} else if t.BankAcctTo != nil {
if ok, err := t.BankAcctTo.Valid(); !ok {
return false, err
}
} else if t.CCAcctTo != nil {
if ok, err := t.CCAcctTo.Valid(); !ok {
return false, err
}
}
if version < OfxVersion220 && len(t.ImageData) > 0 {
return false, errors.New("Transaction.ImageData only supportd for OFX > 220")
} else if len(t.ImageData) > 2 {
return false, errors.New("Only 2 of ImageData allowed in Transaction")
}
var ok1, ok2 bool
if t.Currency != nil {
ok1, _ = t.Currency.Valid()
}
if t.OrigCurrency != nil {
ok2, _ = t.OrigCurrency.Valid()
}
if ok1 && ok2 {
return false, errors.New("Currency and OrigCurrency both supplied for Pending Transaction, only one allowed")
}
return true, nil
}
// TransactionList represents a list of bank transactions, and also includes
// the date range its transactions cover.
type TransactionList struct {
XMLName xml.Name `xml:"BANKTRANLIST"`
DtStart Date `xml:"DTSTART"` // Start date for transaction data
DtEnd Date `xml:"DTEND"` // Value that client should send in next <DTSTART> request to ensure that it does not miss any transactions
Transactions []Transaction `xml:"STMTTRN,omitempty"`
}
// Valid returns (true, nil) if this struct is valid OFX
func (l TransactionList) Valid(version ofxVersion) (bool, error) {
var emptyDate Date
if l.DtStart.Equal(emptyDate) {
return false, errors.New("TransactionList.DtStart not filled")
} else if l.DtEnd.Equal(emptyDate) {
return false, errors.New("TransactionList.DtEnd not filled")
}
for _, t := range l.Transactions {
if ok, err := t.Valid(version); !ok {
return false, err
}
}
return true, nil
}
// PendingTransaction represents a single pending transaction. It is similar to
// Transaction, but is not finalized (and may never be). For instance, it lacks
// FiTID and DtPosted fields.
type PendingTransaction struct {
XMLName xml.Name `xml:"STMTTRNP"`
TrnType trnType `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"`
// Only one of Currency and OrigCurrency can ever be Valid() for the same transaction
Currency Currency `xml:"CURRENCY,omitempty"` // Represents the currency of TrnAmt (instead of CURDEF in STMTRS) if Valid
OrigCurrency Currency `xml:"ORIGCURRENCY,omitempty"` // Represents the currency TrnAmt was converted to STMTRS' CURDEF from if Valid
}
// Valid returns (true, nil) if this struct is valid OFX
func (t PendingTransaction) Valid() (bool, error) {
var emptyDate Date
if !t.TrnType.Valid() {
return false, errors.New("PendingTransaction.TrnType invalid")
} else if t.DtTran.Equal(emptyDate) {
return false, errors.New("PendingTransaction.DtTran not filled")
} else if len(t.Name) == 0 {
return false, errors.New("PendingTransaction.Name empty")
}
ok1, _ := t.Currency.Valid()
ok2, _ := t.OrigCurrency.Valid()
if ok1 && ok2 {
return false, errors.New("Currency and OrigCurrency both supplied for Pending Transaction, only one allowed")
}
return true, nil
}
// PendingTransactionList represents a list of pending transactions, along with
// the date they were generated
type PendingTransactionList struct {
XMLName xml.Name `xml:"BANKTRANLISTP"`
DtAsOf Date `xml:"DTASOF"` // Date and time this set of pending transactions was generated
Transactions []PendingTransaction `xml:"STMTTRNP,omitempty"`
}
// Valid returns (true, nil) if this struct is valid OFX
func (l PendingTransactionList) Valid() (bool, error) {
var emptyDate Date
if l.DtAsOf.Equal(emptyDate) {
return false, errors.New("PendingTransactionList.DtAsOf not filled")
}
for _, t := range l.Transactions {
if ok, err := t.Valid(); !ok {
return false, err
}
}
return true, nil
}
// Balance represents a generic (free-form) balance defined by an FI.
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 balType `xml:"BALTYPE"`
Value Amount `xml:"VALUE"`
DtAsOf *Date `xml:"DTASOF,omitempty"`
Currency *Currency `xml:"CURRENCY,omitempty"` // if BALTYPE is DOLLAR
}
// Valid returns (true, nil) if this struct is valid OFX
func (b Balance) Valid() (bool, error) {
if len(b.Name) == 0 || len(b.Desc) == 0 {
return false, errors.New("Balance Name and Desc not supplied")
}
if !b.BalType.Valid() {
return false, errors.New("Balance BALTYPE not specified")
}
return true, nil
}
// StatementResponse represents a bank account statement, including its
// balances and possibly transactions. It is a response to StatementRequest, or
// sometimes provided as part of an OFX file downloaded manually from an FI.
type StatementResponse struct {
XMLName xml.Name `xml:"STMTTRNRS"`
TrnUID UID `xml:"TRNUID"`
Status Status `xml:"STATUS"`
CltCookie String `xml:"CLTCOOKIE,omitempty"`
// TODO `xml:"OFXEXTENSION,omitempty"`
CurDef CurrSymbol `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
}
// Name returns the name of the top-level transaction XML/SGML element
func (sr *StatementResponse) Name() string {
return "STMTTRNRS"
}
// Valid returns (true, nil) if this struct was valid OFX when unmarshalled
func (sr *StatementResponse) Valid(version ofxVersion) (bool, error) {
var emptyDate Date
if ok, err := sr.TrnUID.Valid(); !ok {
return false, err
} else if ok, err := sr.Status.Valid(); !ok {
return false, err
} else if ok, err := sr.CurDef.Valid(); !ok {
return false, err
} else if ok, err := sr.BankAcctFrom.Valid(); !ok {
return false, err
} else if sr.DtAsOf.Equal(emptyDate) {
return false, errors.New("StatementResponse.DtAsOf not filled")
} else if (sr.AvailBalAmt == nil) != (sr.AvailDtAsOf == nil) {
return false, errors.New("StatementResponse.Avail* must both either be present or absent")
}
if sr.BankTranList != nil {
if ok, err := sr.BankTranList.Valid(version); !ok {
return false, err
}
}
if sr.BankTranListP != nil {
if version < OfxVersion220 {
return false, errors.New("StatementResponse.BankTranListP invalid for OFX < 2.2")
}
if ok, err := sr.BankTranListP.Valid(); !ok {
return false, err
}
}
for _, bal := range sr.BalList {
if ok, err := bal.Valid(); !ok {
return false, err
}
}
return true, nil
}
// Type returns which message set this message belongs to (which Response
// element of type []Message it belongs to)
func (sr *StatementResponse) Type() messageType {
return BankRs
}
================================================
FILE: bank_test.go
================================================
package ofxgo
import (
"strings"
"testing"
"time"
)
func TestMarshalBankStatementRequest(t *testing.T) {
var expectedString string = `<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?OFX OFXHEADER="200" VERSION="203" SECURITY="NONE" OLDFILEUID="NONE" NEWFILEUID="NONE"?>
<OFX>
<SIGNONMSGSRQV1>
<SONRQ>
<DTCLIENT>20060115112300.000[-5:EST]</DTCLIENT>
<USERID>myusername</USERID>
<USERPASS>Pa$$word</USERPASS>
<LANGUAGE>ENG</LANGUAGE>
<FI>
<ORG>BNK</ORG>
<FID>1987</FID>
</FI>
<APPID>OFXGO</APPID>
<APPVER>0001</APPVER>
</SONRQ>
</SIGNONMSGSRQV1>
<BANKMSGSRQV1>
<STMTTRNRQ>
<TRNUID>123</TRNUID>
<STMTRQ>
<BANKACCTFROM>
<BANKID>318398732</BANKID>
<ACCTID>78346129</ACCTID>
<ACCTTYPE>CHECKING</ACCTTYPE>
</BANKACCTFROM>
<INCTRAN>
<INCLUDE>Y</INCLUDE>
</INCTRAN>
</STMTRQ>
</STMTTRNRQ>
</BANKMSGSRQV1>
</OFX>`
var client = BasicClient{
AppID: "OFXGO",
AppVer: "0001",
SpecVersion: OfxVersion203,
}
var request Request
request.Signon.UserID = "myusername"
request.Signon.UserPass = "Pa$$word"
request.Signon.Org = "BNK"
request.Signon.Fid = "1987"
statementRequest := StatementRequest{
TrnUID: "123",
BankAcctFrom: BankAcct{
BankID: "318398732",
AcctID: "78346129",
AcctType: AcctTypeChecking,
},
Include: true,
}
request.Bank = append(request.Bank, &statementRequest)
request.SetClientFields(&client)
// Overwrite the DtClient value set by SetClientFields to time.Now()
EST := time.FixedZone("EST", -5*60*60)
request.Signon.DtClient = *NewDate(2006, 1, 15, 11, 23, 0, 0, EST)
marshalCheckRequest(t, &request, expectedString)
}
func TestMarshalBankStatementRequest103(t *testing.T) {
var expectedString string = `OFXHEADER:100
DATA:OFXSGML
VERSION:103
SECURITY:NONE
ENCODING:USASCII
CHARSET:1252
COMPRESSION:NONE
OLDFILEUID:NONE
NEWFILEUID:NONE
<OFX>
<SIGNONMSGSRQV1>
<SONRQ>
<DTCLIENT>20060115112300.000[-5:EST]
<USERID>myusername
<USERPASS>Pa$$word
<LANGUAGE>ENG
<FI>
<ORG>BNK
<FID>1987
</FI>
<APPID>OFXGO
<APPVER>0001
</SONRQ>
</SIGNONMSGSRQV1>
<BANKMSGSRQV1>
<STMTTRNRQ>
<TRNUID>123
<STMTRQ>
<BANKACCTFROM>
<BANKID>318398732
<ACCTID>78346129
<ACCTTYPE>CHECKING
</BANKACCTFROM>
<INCTRAN>
<INCLUDE>Y
</INCTRAN>
</STMTRQ>
</STMTTRNRQ>
</BANKMSGSRQV1>
</OFX>`
var client = BasicClient{
AppID: "OFXGO",
AppVer: "0001",
SpecVersion: OfxVersion103,
}
var request Request
request.Signon.UserID = "myusername"
request.Signon.UserPass = "Pa$$word"
request.Signon.Org = "BNK"
request.Signon.Fid = "1987"
statementRequest := StatementRequest{
TrnUID: "123",
BankAcctFrom: BankAcct{
BankID: "318398732",
AcctID: "78346129",
AcctType: AcctTypeChecking,
},
Include: true,
}
request.Bank = append(request.Bank, &statementRequest)
request.SetClientFields(&client)
// Overwrite the DtClient value set by SetClientFields to time.Now()
EST := time.FixedZone("EST", -5*60*60)
request.Signon.DtClient = *NewDate(2006, 1, 15, 11, 23, 0, 0, EST)
marshalCheckRequest(t, &request, expectedString)
}
func TestUnmarshalBankStatementResponse(t *testing.T) {
responseReader := strings.NewReader(`<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?OFX OFXHEADER="200" VERSION="203" SECURITY="NONE" OLDFILEUID="NONE" NEWFILEUID="NONE"?>
<OFX>
<SIGNONMSGSRSV1>
<SONRS>
<STATUS>
<CODE>0</CODE>
<SEVERITY>INFO</SEVERITY>
</STATUS>
<DTSERVER>20060115112303</DTSERVER>
<LANGUAGE>ENG</LANGUAGE>
<DTPROFUP>20050221091300</DTPROFUP>
<DTACCTUP>20060102160000</DTACCTUP>
<FI>
<ORG>BNK</ORG>
<FID>1987</FID>
</FI>
</SONRS>
</SIGNONMSGSRSV1>
<BANKMSGSRSV1>
<STMTTRNRS>
<TRNUID>1001</TRNUID>
<STATUS>
<CODE>0</CODE>
<SEVERITY>INFO</SEVERITY>
</STATUS>
<STMTRS>
<CURDEF>USD</CURDEF>
<BANKACCTFROM>
<BANKID>318398732</BANKID>
<ACCTID>78346129</ACCTID>
<ACCTTYPE>CHECKING</ACCTTYPE>
</BANKACCTFROM>
<BANKTRANLIST>
<DTSTART>20060101</DTSTART>
<DTEND>20060115</DTEND>
<STMTTRN>
<TRNTYPE>CHECK</TRNTYPE>
<DTPOSTED>20060104</DTPOSTED>
<TRNAMT>-200.00</TRNAMT>
<FITID>00592</FITID>
<CHECKNUM>2002</CHECKNUM>
</STMTTRN>
<STMTTRN>
<TRNTYPE>ATM</TRNTYPE>
<DTPOSTED>20060112</DTPOSTED>
<DTUSER>20060112</DTUSER>
<TRNAMT>-300.00</TRNAMT>
<FITID>00679</FITID>
</STMTTRN>
</BANKTRANLIST>
<LEDGERBAL>
<BALAMT>200.29</BALAMT>
<DTASOF>200601141600</DTASOF>
</LEDGERBAL>
<AVAILBAL>
<BALAMT>200.29</BALAMT>
<DTASOF>200601141600</DTASOF>
</AVAILBAL>
</STMTRS>
</STMTTRNRS>
</BANKMSGSRSV1>
</OFX>`)
var expected Response
expected.Version = OfxVersion203
expected.Signon.Status.Code = 0
expected.Signon.Status.Severity = "INFO"
expected.Signon.DtServer = *NewDateGMT(2006, 1, 15, 11, 23, 03, 0)
expected.Signon.Language = "ENG"
expected.Signon.DtProfUp = NewDateGMT(2005, 2, 21, 9, 13, 0, 0)
expected.Signon.DtAcctUp = NewDateGMT(2006, 1, 2, 16, 0, 0, 0)
expected.Signon.Org = "BNK"
expected.Signon.Fid = "1987"
var trnamt1, trnamt2 Amount
trnamt1.SetFrac64(-20000, 100)
trnamt2.SetFrac64(-30000, 100)
banktranlist := TransactionList{
DtStart: *NewDateGMT(2006, 1, 1, 0, 0, 0, 0),
DtEnd: *NewDateGMT(2006, 1, 15, 0, 0, 0, 0),
Transactions: []Transaction{
{
TrnType: TrnTypeCheck,
DtPosted: *NewDateGMT(2006, 1, 4, 0, 0, 0, 0),
TrnAmt: trnamt1,
FiTID: "00592",
CheckNum: "2002",
},
{
TrnType: TrnTypeATM,
DtPosted: *NewDateGMT(2006, 1, 12, 0, 0, 0, 0),
DtUser: NewDateGMT(2006, 1, 12, 0, 0, 0, 0),
TrnAmt: trnamt2,
FiTID: "00679",
},
},
}
var balamt, availbalamt Amount
balamt.SetFrac64(20029, 100)
availbalamt.SetFrac64(20029, 100)
usd, err := NewCurrSymbol("USD")
if err != nil {
t.Fatalf("Unexpected error creating CurrSymbol for USD\n")
}
statementResponse := StatementResponse{
TrnUID: "1001",
Status: Status{
Code: 0,
Severity: "INFO",
},
CurDef: *usd,
BankAcctFrom: BankAcct{
BankID: "318398732",
AcctID: "78346129",
AcctType: AcctTypeChecking,
},
BankTranList: &banktranlist,
BalAmt: balamt,
DtAsOf: *NewDateGMT(2006, 1, 14, 16, 0, 0, 0),
AvailBalAmt: &availbalamt,
AvailDtAsOf: NewDateGMT(2006, 1, 14, 16, 0, 0, 0),
}
expected.Bank = append(expected.Bank, &statementResponse)
response, err := ParseResponse(responseReader)
if err != nil {
t.Fatalf("Unexpected error unmarshalling response: %s\n", err)
}
checkResponsesEqual(t, &expected, response)
checkResponseRoundTrip(t, response)
}
func TestPayeeValid(t *testing.T) {
p := Payee{
Name: "Jane",
Addr1: "Sesame Street",
City: "Mytown",
State: "AA",
PostalCode: "12345",
Phone: "12345678901",
}
valid, err := p.Valid()
if !valid {
t.Fatalf("Unexpected error from calling Valid: %s\n", err)
}
// Ensure some empty fields trigger invalid response
badp := p
badp.Name = ""
valid, err = badp.Valid()
if valid || err == nil {
t.Fatalf("Expected error from calling Valid with empty name\n")
}
badp = p
badp.Addr1 = ""
valid, err = badp.Valid()
if valid || err == nil {
t.Fatalf("Expected error from calling Valid with empty address\n")
}
badp = p
badp.City = ""
valid, err = badp.Valid()
if valid || err == nil {
t.Fatalf("Expected error from calling Valid with empty city\n")
}
badp = p
badp.State = ""
valid, err = badp.Valid()
if valid || err == nil {
t.Fatalf("Expected error from calling Valid with empty state\n")
}
badp = p
badp.PostalCode = ""
valid, err = badp.Valid()
if valid || err == nil {
t.Fatalf("Expected error from calling Valid with empty postal code\n")
}
badp = p
badp.Phone = ""
valid, err = badp.Valid()
if valid || err == nil {
t.Fatalf("Expected error from calling Valid with empty phone\n")
}
}
func TestBalanceValid(t *testing.T) {
var a Amount
a.SetFrac64(8, 1)
b := Balance{
Name: "Checking",
Desc: "Jane's Personal Checking",
BalType: BalTypeDollar,
Value: a,
}
valid, err := b.Valid()
if !valid {
t.Fatalf("Unexpected error from calling Valid: %s\n", err)
}
badb := b
badb.Name = ""
valid, err = badb.Valid()
if valid || err == nil {
t.Fatalf("Expected error from calling Valid with empty name\n")
}
badb = b
badb.Desc = ""
valid, err = badb.Valid()
if valid || err == nil {
t.Fatalf("Expected error from calling Valid with empty description\n")
}
badb = Balance{
Name: "Checking",
Desc: "Jane's Personal Checking",
Value: a,
}
valid, err = badb.Valid()
if valid || err == nil {
t.Fatalf("Expected error from calling Valid with unspecified balance type\n")
}
}
================================================
FILE: basic_client.go
================================================
package ofxgo
import (
"errors"
"io"
"net/http"
"strings"
)
// BasicClient provides a standard Client implementation suitable for most
// financial institutions. BasicClient uses default, non-zero settings, even if
// its fields are not initialized.
type BasicClient struct {
// Request fields to overwrite with the client's values. If nonempty,
// defaults are used
SpecVersion ofxVersion // VERSION in header
AppID string // SONRQ>APPID
AppVer string // SONRQ>APPVER
// Don't insert newlines or indentation when marshalling to SGML/XML
NoIndent bool
// Use carriage returns on new lines
CarriageReturn bool
// Set User-Agent header to this string, if not empty
UserAgent string
HTTPClient *http.Client
}
// OfxVersion returns the OFX specification version this BasicClient will marshal
// Requests as. Defaults to "203" if the client's SpecVersion field is empty.
func (c *BasicClient) OfxVersion() ofxVersion {
if c.SpecVersion.Valid() {
return c.SpecVersion
}
return OfxVersion203
}
// ID returns this BasicClient's OFX AppID field, defaulting to "OFXGO" if
// unspecified.
func (c *BasicClient) ID() String {
if len(c.AppID) > 0 {
return String(c.AppID)
}
return String("OFXGO")
}
// Version returns this BasicClient's version number as a string, defaulting to
// "0001" if unspecified.
func (c *BasicClient) Version() String {
if len(c.AppVer) > 0 {
return String(c.AppVer)
}
return String("0001")
}
// IndentRequests returns true if the marshaled XML should be indented (and
// contain newlines, since the two are linked in the current implementation)
func (c *BasicClient) IndentRequests() bool {
return !c.NoIndent
}
// CarriageReturnNewLines returns true if carriage returns should be used on new lines, false otherwise
func (c *BasicClient) CarriageReturnNewLines() bool {
return c.CarriageReturn
}
// RawRequest is a convenience wrapper around http.Post. It is exposed only for
// when you need to read/inspect the raw HTTP response yourself.
func (c *BasicClient) RawRequest(URL string, r io.Reader) (*http.Response, error) {
if !strings.HasPrefix(URL, "https://") {
return nil, errors.New("Refusing to send OFX request with possible plain-text password over non-https protocol")
}
httpClient := c.HTTPClient
if httpClient == nil {
httpClient = http.DefaultClient
}
request, err := http.NewRequest("POST", URL, r)
if err != nil {
return nil, err
}
request.Header.Set("Content-Type", "application/x-ofx")
request.Header.Add("Accept", "*/*, application/x-ofx")
if c.UserAgent != "" {
request.Header.Set("User-Agent", c.UserAgent)
}
response, err := httpClient.Do(request)
if err != nil {
return nil, err
}
if response.StatusCode != 200 {
return response, errors.New("OFXQuery request status: " + response.Status)
}
return response, nil
}
// RequestNoParse marshals a Request to XML, makes an HTTP request, and returns
// the raw HTTP response
func (c *BasicClient) RequestNoParse(r *Request) (*http.Response, error) {
return clientRequestNoParse(c, r)
}
// Request marshals a Request to XML, makes an HTTP request, and then
// unmarshals the response into a Response object.
func (c *BasicClient) Request(r *Request) (*Response, error) {
return clientRequest(c, r)
}
================================================
FILE: basic_client_test.go
================================================
package ofxgo
import (
"errors"
"net"
"net/http"
"strings"
"testing"
)
func TestBasicClient_HTTPClient(t *testing.T) {
c := &BasicClient{
HTTPClient: &http.Client{
Transport: &http.Transport{
Dial: func(network, addr string) (net.Conn, error) {
return nil, errors.New("bad test client")
},
},
},
}
_, err := c.Request(&Request{
URL: "https://test",
Signon: SignonRequest{
UserID: "test",
UserPass: "test",
},
})
if err == nil || !strings.Contains(err.Error(), "bad test client") {
t.Fatalf("expected error containing 'bad test client', got: %v", err)
}
}
================================================
FILE: client.go
================================================
package ofxgo
import (
"io"
"net/http"
"strings"
)
// Client serves to aggregate OFX client settings that may be necessary to talk
// to a particular server due to quirks in that server's implementation.
// Client also provides the Request and RequestNoParse helper methods to aid in
// making and parsing requests.
type Client interface {
// Used to fill out a Request object
OfxVersion() ofxVersion
ID() String
Version() String
IndentRequests() bool
CarriageReturnNewLines() bool
// Request marshals a Request object into XML, makes an HTTP request
// against it's URL, and then unmarshals the response into a Response
// object.
//
// Before being marshaled, some of the the Request object's values are
// overwritten, namely those dictated by the BasicClient's configuration
// (Version, AppID, AppVer fields), and the client's current time
// (DtClient). These are updated in place in the supplied Request object so
// they may later be inspected by the caller.
Request(r *Request) (*Response, error)
// RequestNoParse marshals a Request object into XML, makes an HTTP
// request, and returns the raw HTTP response. Unlike RawRequest(), it
// takes client settings into account. Unlike Request(), it doesn't parse
// the response into an ofxgo.Request object.
//
// Caveat: The caller is responsible for closing the http Response.Body
// (see the http module's documentation for more information)
RequestNoParse(r *Request) (*http.Response, error)
// RawRequest is little more than a thin wrapper around http.Post
//
// In most cases, you should probably be using Request() instead, but
// RawRequest can be useful if you need to read the raw unparsed http
// response yourself (perhaps for downloading an OFX file for use by an
// external program, or debugging server behavior), or have a handcrafted
// request you'd like to try.
//
// Caveats: RawRequest does *not* take client settings into account as
// Client.Request() does, so your particular server may or may not like
// whatever we read from 'r'. The caller is responsible for closing the
// http Response.Body (see the http module's documentation for more
// information)
RawRequest(URL string, r io.Reader) (*http.Response, error)
}
type clientCreationFunc func(*BasicClient) Client
// GetClient returns a new Client for a given URL. It attempts to find a
// specialized client for this URL, but simply returns the passed-in
// BasicClient if no such match is found.
func GetClient(URL string, bc *BasicClient) Client {
clients := []struct {
URL string
Func clientCreationFunc
}{
{"https://ofx.discovercard.com", NewDiscoverCardClient},
{"https://vesnc.vanguard.com/us/OfxDirectConnectServlet", NewVanguardClient},
}
for _, client := range clients {
if client.URL == strings.Trim(URL, "/") {
return client.Func(bc)
}
}
return bc
}
// clientRequestNoParse can be used for building clients' RequestNoParse
// methods if they require fairly standard behavior
func clientRequestNoParse(c Client, r *Request) (*http.Response, error) {
r.SetClientFields(c)
b, err := r.Marshal()
if err != nil {
return nil, err
}
return c.RawRequest(r.URL, b)
}
// clientRequest can be used for building clients' Request methods if they
// require fairly standard behavior
func clientRequest(c Client, r *Request) (*Response, error) {
response, err := c.RequestNoParse(r)
if err != nil {
return nil, err
}
defer response.Body.Close()
ofxresp, err := ParseResponse(response.Body)
if err != nil {
return nil, err
}
return ofxresp, nil
}
================================================
FILE: cmd/ofx/bankdownload.go
================================================
package main
import (
"flag"
"fmt"
"github.com/aclindsa/ofxgo"
"io"
"os"
)
var downloadCommand = command{
Name: "download-bank",
Description: "Download a bank account statement to a file",
Flags: flag.NewFlagSet("download-bank", flag.ExitOnError),
CheckFlags: downloadCheckFlags,
Do: download,
}
var filename, bankID, acctID, acctType string
func init() {
defineServerFlags(downloadCommand.Flags)
downloadCommand.Flags.StringVar(&filename, "filename", "./response.ofx", "The file to save to")
downloadCommand.Flags.StringVar(&bankID, "bankid", "", "BankID (from `get-accounts` subcommand)")
downloadCommand.Flags.StringVar(&acctID, "acctid", "", "AcctID (from `get-accounts` subcommand)")
downloadCommand.Flags.StringVar(&acctType, "accttype", "CHECKING", "AcctType (from `get-accounts` subcommand)")
}
func downloadCheckFlags() bool {
ret := checkServerFlags()
if len(filename) == 0 {
fmt.Println("Error: Filename empty")
return false
}
return ret
}
func download() {
client, query := newRequest()
acctTypeEnum, err := ofxgo.NewAcctType(acctType)
if err != nil {
fmt.Println("Error parsing accttype:", err)
os.Exit(1)
}
uid, err := ofxgo.RandomUID()
if err != nil {
fmt.Println("Error creating uid for transaction:", err)
os.Exit(1)
}
statementRequest := ofxgo.StatementRequest{
TrnUID: *uid,
BankAcctFrom: ofxgo.BankAcct{
BankID: ofxgo.String(bankID),
AcctID: ofxgo.String(acctID),
AcctType: acctTypeEnum,
},
Include: true,
}
query.Bank = append(query.Bank, &statementRequest)
if dryrun {
printRequest(client, query)
return
}
response, err := client.RequestNoParse(query)
if err != nil {
fmt.Println("Error requesting account statement:", err)
os.Exit(1)
}
defer response.Body.Close()
file, err := os.Create(filename)
if err != nil {
fmt.Println("Error creating file to write to:", err)
os.Exit(1)
}
defer file.Close()
_, err = io.Copy(file, response.Body)
if err != nil {
fmt.Println("Error writing response to file:", err)
os.Exit(1)
}
}
================================================
FILE: cmd/ofx/banktransactions.go
================================================
package main
import (
"flag"
"fmt"
"github.com/aclindsa/ofxgo"
"os"
)
var bankTransactionsCommand = command{
Name: "transactions-bank",
Description: "Print bank transactions and balance",
Flags: flag.NewFlagSet("transactions-bank", flag.ExitOnError),
CheckFlags: checkServerFlags,
Do: bankTransactions,
}
func init() {
defineServerFlags(bankTransactionsCommand.Flags)
bankTransactionsCommand.Flags.StringVar(&bankID, "bankid", "", "BankID (from `get-accounts` subcommand)")
bankTransactionsCommand.Flags.StringVar(&acctID, "acctid", "", "AcctID (from `get-accounts` subcommand)")
bankTransactionsCommand.Flags.StringVar(&acctType, "accttype", "CHECKING", "AcctType (from `get-accounts` subcommand)")
}
func bankTransactions() {
client, query := newRequest()
acctTypeEnum, err := ofxgo.NewAcctType(acctType)
if err != nil {
fmt.Println("Error parsing accttype:", err)
os.Exit(1)
}
uid, err := ofxgo.RandomUID()
if err != nil {
fmt.Println("Error creating uid for transaction:", err)
os.Exit(1)
}
statementRequest := ofxgo.StatementRequest{
TrnUID: *uid,
BankAcctFrom: ofxgo.BankAcct{
BankID: ofxgo.String(bankID),
AcctID: ofxgo.String(acctID),
AcctType: acctTypeEnum,
},
Include: true,
}
query.Bank = append(query.Bank, &statementRequest)
if dryrun {
printRequest(client, query)
return
}
response, err := client.Request(query)
if err != nil {
fmt.Println("Error requesting account statement:", err)
os.Exit(1)
}
if response.Signon.Status.Code != 0 {
meaning, _ := response.Signon.Status.CodeMeaning()
fmt.Printf("Nonzero signon status (%d: %s) with message: %s\n", response.Signon.Status.Code, meaning, response.Signon.Status.Message)
os.Exit(1)
}
if len(response.Bank) < 1 {
fmt.Println("No banking messages received")
return
}
if stmt, ok := response.Bank[0].(*ofxgo.StatementResponse); ok {
fmt.Printf("Balance: %s %s (as of %s)\n", stmt.BalAmt, stmt.CurDef, stmt.DtAsOf)
fmt.Println("Transactions:")
for _, tran := range stmt.BankTranList.Transactions {
printTransaction(stmt.CurDef, &tran)
}
}
}
func printTransaction(defCurrency ofxgo.CurrSymbol, tran *ofxgo.Transaction) {
currency := defCurrency
if tran.Currency != nil {
currency = tran.Currency.CurSym
}
var name string
if len(tran.Name) > 0 {
name = string(tran.Name)
} else if tran.Payee != nil {
name = string(tran.Payee.Name)
}
if len(tran.Memo) > 0 {
name = name + " - " + string(tran.Memo)
}
fmt.Printf("%s %-15s %-11s %s\n", tran.DtPosted, tran.TrnAmt.String()+" "+currency.String(), tran.TrnType, name)
}
================================================
FILE: cmd/ofx/ccdownload.go
================================================
package main
import (
"flag"
"fmt"
"github.com/aclindsa/ofxgo"
"io"
"os"
)
var ccDownloadCommand = command{
Name: "download-cc",
Description: "Download a credit card account statement to a file",
Flags: flag.NewFlagSet("download-cc", flag.ExitOnError),
CheckFlags: ccDownloadCheckFlags,
Do: ccDownload,
}
func init() {
defineServerFlags(ccDownloadCommand.Flags)
ccDownloadCommand.Flags.StringVar(&filename, "filename", "./response.ofx", "The file to save to")
ccDownloadCommand.Flags.StringVar(&acctID, "acctid", "", "AcctID (from `get-accounts` subcommand)")
}
func ccDownloadCheckFlags() bool {
ret := checkServerFlags()
if len(filename) == 0 {
fmt.Println("Error: Filename empty")
return false
}
return ret
}
func ccDownload() {
client, query := newRequest()
uid, err := ofxgo.RandomUID()
if err != nil {
fmt.Println("Error creating uid for transaction:", err)
os.Exit(1)
}
statementRequest := ofxgo.CCStatementRequest{
TrnUID: *uid,
CCAcctFrom: ofxgo.CCAcct{
AcctID: ofxgo.String(acctID),
},
Include: true,
}
query.CreditCard = append(query.CreditCard, &statementRequest)
if dryrun {
printRequest(client, query)
return
}
response, err := client.RequestNoParse(query)
if err != nil {
fmt.Println("Error requesting account statement:", err)
os.Exit(1)
}
defer response.Body.Close()
file, err := os.Create(filename)
if err != nil {
fmt.Println("Error creating file to write to:", err)
os.Exit(1)
}
defer file.Close()
_, err = io.Copy(file, response.Body)
if err != nil {
fmt.Println("Error writing response to file:", err)
os.Exit(1)
}
}
================================================
FILE: cmd/ofx/cctransactions.go
================================================
package main
import (
"flag"
"fmt"
"github.com/aclindsa/ofxgo"
"os"
)
var ccTransactionsCommand = command{
Name: "transactions-cc",
Description: "Print credit card transactions and balance",
Flags: flag.NewFlagSet("transactions-cc", flag.ExitOnError),
CheckFlags: checkServerFlags,
Do: ccTransactions,
}
func init() {
defineServerFlags(ccTransactionsCommand.Flags)
ccTransactionsCommand.Flags.StringVar(&acctID, "acctid", "", "AcctID (from `get-accounts` subcommand)")
}
func ccTransactions() {
client, query := newRequest()
uid, err := ofxgo.RandomUID()
if err != nil {
fmt.Println("Error creating uid for transaction:", err)
os.Exit(1)
}
statementRequest := ofxgo.CCStatementRequest{
TrnUID: *uid,
CCAcctFrom: ofxgo.CCAcct{
AcctID: ofxgo.String(acctID),
},
Include: true,
}
query.CreditCard = append(query.CreditCard, &statementRequest)
if dryrun {
printRequest(client, query)
return
}
response, err := client.Request(query)
if err != nil {
fmt.Println("Error requesting account statement:", err)
os.Exit(1)
}
if response.Signon.Status.Code != 0 {
meaning, _ := response.Signon.Status.CodeMeaning()
fmt.Printf("Nonzero signon status (%d: %s) with message: %s\n", response.Signon.Status.Code, meaning, response.Signon.Status.Message)
os.Exit(1)
}
if len(response.CreditCard) < 1 {
fmt.Println("No banking messages received")
return
}
if stmt, ok := response.CreditCard[0].(*ofxgo.CCStatementResponse); ok {
fmt.Printf("Balance: %s %s (as of %s)\n", stmt.BalAmt, stmt.CurDef, stmt.DtAsOf)
fmt.Println("Transactions:")
for _, tran := range stmt.BankTranList.Transactions {
currency := stmt.CurDef
if tran.Currency != nil {
currency = tran.Currency.CurSym
}
var name string
if len(tran.Name) > 0 {
name = string(tran.Name)
} else {
name = string(tran.Payee.Name)
}
if len(tran.Memo) > 0 {
name = name + " - " + string(tran.Memo)
}
fmt.Printf("%s %-15s %-11s %s\n", tran.DtPosted, tran.TrnAmt.String()+" "+currency.String(), tran.TrnType, name)
}
}
}
================================================
FILE: cmd/ofx/command.go
================================================
package main
import (
"flag"
"fmt"
"golang.org/x/term"
"os"
)
type command struct {
Name string
Description string
Flags *flag.FlagSet
CheckFlags func() bool // Check the flag values after they're parsed, printing errors and returning false if they're incorrect
Do func() // Run the command (only called if CheckFlags returns true)
}
func (c *command) usage() {
fmt.Printf("Usage of %s:\n", c.Name)
c.Flags.PrintDefaults()
}
// flags common to all server transactions
var serverURL, username, password, org, fid, appID, appVer, ofxVersion, clientUID string
var noIndentRequests bool
var carriageReturn bool
var dryrun bool
var userAgent string
func defineServerFlags(f *flag.FlagSet) {
f.StringVar(&serverURL, "url", "", "Financial institution's OFX Server URL (see ofxhome.com if you don't know it)")
f.StringVar(&username, "username", "", "Your username at financial institution")
f.StringVar(&password, "password", "", "Your password at financial institution")
f.StringVar(&org, "org", "", "'ORG' for your financial institution")
f.StringVar(&fid, "fid", "", "'FID' for your financial institution")
f.StringVar(&appID, "appid", "QWIN", "'APPID' to pretend to be")
f.StringVar(&appVer, "appver", "2400", "'APPVER' to pretend to be")
f.StringVar(&ofxVersion, "ofxversion", "203", "OFX version to use")
f.StringVar(&clientUID, "clientuid", "", "Client UID (only required by a few FIs, like Chase)")
f.BoolVar(&noIndentRequests, "noindent", false, "Don't indent OFX requests")
f.BoolVar(&carriageReturn, "carriagereturn", false, "Use carriage return as line separator")
f.StringVar(&userAgent, "useragent", "", "Use string as User-Agent header when sending request")
f.BoolVar(&dryrun, "dryrun", false, "Don't send request - print content of request instead")
}
func checkServerFlags() bool {
var ret bool = true
if len(serverURL) == 0 {
fmt.Println("Error: Server URL empty")
ret = false
}
if len(username) == 0 {
fmt.Println("Error: Username empty")
ret = false
}
if ret && len(password) == 0 {
fmt.Printf("Password for %s: ", username)
pass, err := term.ReadPassword(int(os.Stdin.Fd()))
if err != nil {
fmt.Printf("Error reading password: %s\n", err)
ret = false
} else {
password = string(pass)
}
}
return ret
}
================================================
FILE: cmd/ofx/detect_settings.go
================================================
package main
import (
"flag"
"fmt"
"github.com/aclindsa/ofxgo"
"os"
"time"
)
var detectSettingsCommand = command{
Name: "detect-settings",
Description: "Attempt to guess client settings needed for a particular financial institution",
Flags: flag.NewFlagSet("detect-settings", flag.ExitOnError),
CheckFlags: checkServerFlags,
Do: detectSettings,
}
var delay uint64
func init() {
detectSettingsCommand.Flags.StringVar(&serverURL, "url", "", "Financial institution's OFX Server URL (see ofxhome.com if you don't know it)")
detectSettingsCommand.Flags.StringVar(&username, "username", "", "Your username at financial institution")
detectSettingsCommand.Flags.StringVar(&password, "password", "", "Your password at financial institution")
detectSettingsCommand.Flags.StringVar(&org, "org", "", "'ORG' for your financial institution")
detectSettingsCommand.Flags.StringVar(&fid, "fid", "", "'FID' for your financial institution")
detectSettingsCommand.Flags.Uint64Var(&delay, "delay", 500, "How long to delay between two subsequent requests, in milliseconds")
}
// We keep a separate list of APPIDs to preserve the ordering (ordering isn't
// guaranteed in maps). We want to try them in order from 'best' and most
// likely to work to 'worse' and least likely to work
var appIDs = []string{
"OFXGO", // ofxgo (this library)
"QWIN", // Intuit Quicken Windows
"QMOFX", // Intuit Quicken Mac
"QB", // Intuit QuickBooks Windows
"Money", // Microsoft Money 2007
}
var appVersions = map[string][]string{
"OFXGO": { // ofxgo (this library)
"0001",
},
"QWIN": { // Intuit Quicken Windows
"2600", // 2017
"2500", // 2016
"2400", // 2015
"2300", // 2014
"2200", // 2013
"2100", // 2012
"2000", // 2011
"1900", // 2010
"1800", // 2009
"1700", // 2008
"1600", // 2007
"1500", // 2006
"1400", // 2005
},
"QMOFX": { // Intuit Quicken Mac
"1700", // 2008
"1600", // 2007
"1500", // 2006
"1400", // 2005
},
"QB": { // Intuit QuickBooks Windows
"1800", // 2008
"1700", // 2007
"1600", // 2006
"1500", // 2005
},
"Money": { // Microsoft Money 2007
"1600", // 2007
"1500", // 2006
"1400", // 2005
"1200", // 2004
"1100", // 2003
},
}
var versions = []string{
"203",
"103",
"200",
"201",
"202",
"210",
"211",
"102",
"151",
"160",
"220",
}
func detectSettings() {
var attempts uint
for _, appID := range appIDs {
for _, appVer := range appVersions[appID] {
for _, version := range versions {
for _, noIndent := range []bool{false, true} {
if tryProfile(appID, appVer, version, noIndent) {
fmt.Println("The following settings were found to work:")
fmt.Printf("AppID: %s\n", appID)
fmt.Printf("AppVer: %s\n", appVer)
fmt.Printf("OFX Version: %s\n", version)
fmt.Printf("noindent: %t\n", noIndent)
os.Exit(0)
} else {
attempts++
var noIndentString string
if noIndent {
noIndentString = " noindent"
}
fmt.Printf("Attempt %d failed (%s %s %s%s), trying again after %dms...\n", attempts, appID, appVer, version, noIndentString, delay)
time.Sleep(time.Duration(delay) * time.Millisecond)
}
}
}
}
}
}
const anonymous = "anonymous00000000000000000000000"
func tryProfile(appID, appVer, version string, noindent bool) bool {
ver, err := ofxgo.NewOfxVersion(version)
if err != nil {
fmt.Println("Error creating new OfxVersion enum:", err)
os.Exit(1)
}
var client = ofxgo.GetClient(serverURL,
&ofxgo.BasicClient{
AppID: appID,
AppVer: appVer,
SpecVersion: ver,
NoIndent: noindent,
})
var query ofxgo.Request
query.URL = serverURL
query.Signon.ClientUID = ofxgo.UID(clientUID)
query.Signon.UserID = ofxgo.String(username)
query.Signon.UserPass = ofxgo.String(password)
query.Signon.Org = ofxgo.String(org)
query.Signon.Fid = ofxgo.String(fid)
uid, err := ofxgo.RandomUID()
if err != nil {
fmt.Println("Error creating uid for transaction:", err)
os.Exit(1)
}
profileRequest := ofxgo.ProfileRequest{
TrnUID: *uid,
DtProfUp: ofxgo.Date{Time: time.Unix(0, 0)},
}
query.Prof = append(query.Prof, &profileRequest)
_, err = client.Request(&query)
if err == nil {
return true
}
// try again with anonymous logins
query.Signon.UserID = ofxgo.String(anonymous)
query.Signon.UserPass = ofxgo.String(anonymous)
_, err = client.Request(&query)
return err == nil
}
================================================
FILE: cmd/ofx/get_accounts.go
================================================
package main
import (
"flag"
"fmt"
"github.com/aclindsa/ofxgo"
"os"
"time"
)
var getAccountsCommand = command{
Name: "get-accounts",
Description: "List accounts at your financial institution",
Flags: flag.NewFlagSet("get-accounts", flag.ExitOnError),
CheckFlags: checkServerFlags,
Do: getAccounts,
}
func init() {
defineServerFlags(getAccountsCommand.Flags)
}
func getAccounts() {
client, query := newRequest()
uid, err := ofxgo.RandomUID()
if err != nil {
fmt.Println("Error creating uid for transaction:", err)
os.Exit(1)
}
acctInfo := ofxgo.AcctInfoRequest{
TrnUID: *uid,
DtAcctUp: ofxgo.Date{Time: time.Unix(0, 0)},
}
query.Signup = append(query.Signup, &acctInfo)
if dryrun {
printRequest(client, query)
return
}
response, err := client.Request(query)
if err != nil {
fmt.Println("Error requesting account information:", err)
os.Exit(1)
}
if response.Signon.Status.Code != 0 {
meaning, _ := response.Signon.Status.CodeMeaning()
fmt.Printf("Nonzero signon status (%d: %s) with message: %s\n", response.Signon.Status.Code, meaning, response.Signon.Status.Message)
os.Exit(1)
}
if len(response.Signup) < 1 {
fmt.Println("No signup messages received")
return
}
fmt.Printf("\nFound the following accounts:\n\n")
if acctinfo, ok := response.Signup[0].(*ofxgo.AcctInfoResponse); ok {
for _, acct := range acctinfo.AcctInfo {
if acct.BankAcctInfo != nil {
fmt.Printf("Bank Account:\n\tBankID: \"%s\"\n\tAcctID: \"%s\"\n\tAcctType: %s\n", acct.BankAcctInfo.BankAcctFrom.BankID, acct.BankAcctInfo.BankAcctFrom.AcctID, acct.BankAcctInfo.BankAcctFrom.AcctType)
} else if acct.CCAcctInfo != nil {
fmt.Printf("Credit card:\n\tAcctID: \"%s\"\n", acct.CCAcctInfo.CCAcctFrom.AcctID)
} else if acct.InvAcctInfo != nil {
fmt.Printf("Investment account:\n\tBrokerID: \"%s\"\n\tAcctID: \"%s\"\n", acct.InvAcctInfo.InvAcctFrom.BrokerID, acct.InvAcctInfo.InvAcctFrom.AcctID)
} else {
fmt.Printf("Unknown type: %s %s\n", acct.Name, acct.Desc)
}
}
}
}
================================================
FILE: cmd/ofx/invdownload.go
================================================
package main
import (
"flag"
"fmt"
"github.com/aclindsa/ofxgo"
"io"
"os"
)
var invDownloadCommand = command{
Name: "download-inv",
Description: "Download a investment account statement to a file",
Flags: flag.NewFlagSet("download-inv", flag.ExitOnError),
CheckFlags: invDownloadCheckFlags,
Do: invDownload,
}
var brokerID string
func init() {
defineServerFlags(invDownloadCommand.Flags)
invDownloadCommand.Flags.StringVar(&filename, "filename", "./response.ofx", "The file to save to")
invDownloadCommand.Flags.StringVar(&acctID, "acctid", "", "AcctID (from `get-accounts` subcommand)")
invDownloadCommand.Flags.StringVar(&brokerID, "brokerid", "", "BrokerID (from `get-accounts` subcommand)")
}
func invDownloadCheckFlags() bool {
ret := checkServerFlags()
if len(filename) == 0 {
fmt.Println("Error: Filename empty")
return false
}
return ret
}
func invDownload() {
client, query := newRequest()
uid, err := ofxgo.RandomUID()
if err != nil {
fmt.Println("Error creating uid for transaction:", err)
os.Exit(1)
}
statementRequest := ofxgo.InvStatementRequest{
TrnUID: *uid,
InvAcctFrom: ofxgo.InvAcct{
BrokerID: ofxgo.String(brokerID),
AcctID: ofxgo.String(acctID),
},
Include: true,
IncludeOO: true,
IncludePos: true,
IncludeBalance: true,
Include401K: true,
Include401KBal: true,
}
query.InvStmt = append(query.InvStmt, &statementRequest)
if dryrun {
printRequest(client, query)
return
}
response, err := client.RequestNoParse(query)
if err != nil {
fmt.Println("Error requesting account statement:", err)
os.Exit(1)
}
defer response.Body.Close()
file, err := os.Create(filename)
if err != nil {
fmt.Println("Error creating file to write to:", err)
os.Exit(1)
}
defer file.Close()
_, err = io.Copy(file, response.Body)
if err != nil {
fmt.Println("Error writing response to file:", err)
os.Exit(1)
}
}
================================================
FILE: cmd/ofx/invtransactions.go
================================================
package main
import (
"flag"
"fmt"
"github.com/aclindsa/ofxgo"
"os"
)
var invTransactionsCommand = command{
Name: "transactions-inv",
Description: "Print investment transactions",
Flags: flag.NewFlagSet("transactions-inv", flag.ExitOnError),
CheckFlags: checkServerFlags,
Do: invTransactions,
}
func init() {
defineServerFlags(invTransactionsCommand.Flags)
invTransactionsCommand.Flags.StringVar(&acctID, "acctid", "", "AcctID (from `get-accounts` subcommand)")
invTransactionsCommand.Flags.StringVar(&brokerID, "brokerid", "", "BrokerID (from `get-accounts` subcommand)")
}
func invTransactions() {
client, query := newRequest()
uid, err := ofxgo.RandomUID()
if err != nil {
fmt.Println("Error creating uid for transaction:", err)
os.Exit(1)
}
statementRequest := ofxgo.InvStatementRequest{
TrnUID: *uid,
InvAcctFrom: ofxgo.InvAcct{
BrokerID: ofxgo.String(brokerID),
AcctID: ofxgo.String(acctID),
},
Include: true,
IncludeOO: true,
IncludePos: true,
IncludeBalance: true,
Include401K: true,
Include401KBal: true,
}
query.InvStmt = append(query.InvStmt, &statementRequest)
if dryrun {
printRequest(client, query)
return
}
response, err := client.Request(query)
if err != nil {
os.Exit(1)
}
if response.Signon.Status.Code != 0 {
meaning, _ := response.Signon.Status.CodeMeaning()
fmt.Printf("Nonzero signon status (%d: %s) with message: %s\n", response.Signon.Status.Code, meaning, response.Signon.Status.Message)
os.Exit(1)
}
if len(response.InvStmt) < 1 {
fmt.Println("No investment messages received")
return
}
if stmt, ok := response.InvStmt[0].(*ofxgo.InvStatementResponse); ok {
availCash := stmt.InvBal.AvailCash
if availCash.IsInt() && availCash.Num().Int64() != 0 {
fmt.Printf("Balance: %s %s (as of %s)\n", stmt.InvBal.AvailCash, stmt.CurDef, stmt.DtAsOf)
}
for _, banktrans := range stmt.InvTranList.BankTransactions {
fmt.Printf("\nBank Transactions for %s subaccount:\n", banktrans.SubAcctFund)
for _, tran := range banktrans.Transactions {
printTransaction(stmt.CurDef, &tran)
}
}
fmt.Printf("\nInvestment Transactions:\n")
for _, t := range stmt.InvTranList.InvTransactions {
fmt.Printf("%-14s", t.TransactionType())
switch tran := t.(type) {
case ofxgo.BuyDebt:
printInvBuy(stmt.CurDef, &tran.InvBuy)
case ofxgo.BuyMF:
printInvBuy(stmt.CurDef, &tran.InvBuy)
case ofxgo.BuyOpt:
printInvBuy(stmt.CurDef, &tran.InvBuy)
case ofxgo.BuyOther:
printInvBuy(stmt.CurDef, &tran.InvBuy)
case ofxgo.BuyStock:
printInvBuy(stmt.CurDef, &tran.InvBuy)
case ofxgo.ClosureOpt:
printInvTran(&tran.InvTran)
fmt.Printf("%s %s contracts (%d shares each)\n", tran.OptAction, tran.Units, tran.ShPerCtrct)
case ofxgo.Income:
printInvTran(&tran.InvTran)
currency := stmt.CurDef
if ok, _ := tran.Currency.Valid(); ok {
currency = tran.Currency.CurSym
}
fmt.Printf(" %s %s %s (%s %s)\n", tran.IncomeType, tran.Total, currency, tran.SecID.UniqueIDType, tran.SecID.UniqueID)
// TODO print ticker instead of CUSIP
case ofxgo.InvExpense:
printInvTran(&tran.InvTran)
currency := stmt.CurDef
if ok, _ := tran.Currency.Valid(); ok {
currency = tran.Currency.CurSym
}
fmt.Printf(" %s %s (%s %s)\n", tran.Total, currency, tran.SecID.UniqueIDType, tran.SecID.UniqueID)
// TODO print ticker instead of CUSIP
case ofxgo.JrnlFund:
printInvTran(&tran.InvTran)
fmt.Printf(" %s %s (%s -> %s)\n", tran.Total, stmt.CurDef, tran.SubAcctFrom, tran.SubAcctTo)
case ofxgo.JrnlSec:
printInvTran(&tran.InvTran)
fmt.Printf(" %s %s %s (%s -> %s)\n", tran.Units, tran.SecID.UniqueIDType, tran.SecID.UniqueID, tran.SubAcctFrom, tran.SubAcctTo)
// TODO print ticker instead of CUSIP
case ofxgo.MarginInterest:
printInvTran(&tran.InvTran)
currency := stmt.CurDef
if ok, _ := tran.Currency.Valid(); ok {
currency = tran.Currency.CurSym
}
fmt.Printf(" %s %s\n", tran.Total, currency)
case ofxgo.Reinvest:
printInvTran(&tran.InvTran)
currency := stmt.CurDef
if ok, _ := tran.Currency.Valid(); ok {
currency = tran.Currency.CurSym
}
fmt.Printf(" %s (%s %s)@%s %s (Total: %s)\n", tran.Units, tran.SecID.UniqueIDType, tran.SecID.UniqueID, tran.UnitPrice, currency, tran.Total)
// TODO print ticker instead of CUSIP
case ofxgo.RetOfCap:
printInvTran(&tran.InvTran)
currency := stmt.CurDef
if ok, _ := tran.Currency.Valid(); ok {
currency = tran.Currency.CurSym
}
fmt.Printf(" %s %s (%s %s)\n", tran.Total, currency, tran.SecID.UniqueIDType, tran.SecID.UniqueID)
// TODO print ticker instead of CUSIP
case ofxgo.SellDebt:
printInvSell(stmt.CurDef, &tran.InvSell)
case ofxgo.SellMF:
printInvSell(stmt.CurDef, &tran.InvSell)
case ofxgo.SellOpt:
printInvSell(stmt.CurDef, &tran.InvSell)
case ofxgo.SellOther:
printInvSell(stmt.CurDef, &tran.InvSell)
case ofxgo.SellStock:
printInvSell(stmt.CurDef, &tran.InvSell)
case ofxgo.Split:
printInvTran(&tran.InvTran)
currency := stmt.CurDef
if ok, _ := tran.Currency.Valid(); ok {
currency = tran.Currency.CurSym
}
fmt.Printf(" %d/%d %s -> %s shares of %s %s (%s %s for fractional shares)\n", tran.Numerator, tran.Denominator, tran.OldUnits, tran.NewUnits, tran.SecID.UniqueIDType, tran.SecID.UniqueID, tran.FracCash, currency)
// TODO print ticker instead of CUSIP
case ofxgo.Transfer:
printInvTran(&tran.InvTran)
fmt.Printf(" %s (%s %s) %s\n", tran.Units, tran.SecID.UniqueIDType, tran.SecID.UniqueID, tran.TferAction)
// TODO print ticker instead of CUSIP
}
}
}
}
func printInvTran(it *ofxgo.InvTran) {
fmt.Printf("%s", it.DtTrade)
}
func printInvBuy(defCurrency ofxgo.CurrSymbol, ib *ofxgo.InvBuy) {
printInvTran(&ib.InvTran)
currency := defCurrency
if ok, _ := ib.Currency.Valid(); ok {
currency = ib.Currency.CurSym
}
fmt.Printf("%s (%s %s)@%s %s (Total: %s)\n", ib.Units, ib.SecID.UniqueIDType, ib.SecID.UniqueID, ib.UnitPrice, currency, ib.Total)
// TODO print ticker instead of CUSIP
}
func printInvSell(defCurrency ofxgo.CurrSymbol, is *ofxgo.InvSell) {
printInvTran(&is.InvTran)
currency := defCurrency
if ok, _ := is.Currency.Valid(); ok {
currency = is.Currency.CurSym
}
fmt.Printf(" %s (%s %s)@%s %s (Total: %s)\n", is.Units, is.SecID.UniqueIDType, is.SecID.UniqueID, is.UnitPrice, currency.String(), is.Total)
// TODO print ticker instead of CUSIP
}
================================================
FILE: cmd/ofx/main.go
================================================
package main
import (
"fmt"
"os"
"strconv"
)
var commands = []command{
profileDownloadCommand,
getAccountsCommand,
downloadCommand,
ccDownloadCommand,
invDownloadCommand,
bankTransactionsCommand,
ccTransactionsCommand,
invTransactionsCommand,
detectSettingsCommand,
}
func usage() {
fmt.Println(`The ofxgo command-line client provides a simple interface to
query, parse, and display financial data via the OFX specification.
Usage:
ofx command [arguments]
The commands are:`)
maxlen := 0
for _, cmd := range commands {
if len(cmd.Name) > maxlen {
maxlen = len(cmd.Name)
}
}
formatString := " %-" + strconv.Itoa(maxlen) + "s %s\n"
for _, cmd := range commands {
fmt.Printf(formatString, cmd.Name, cmd.Description)
}
}
func runCmd(c *command) {
err := c.Flags.Parse(os.Args[2:])
if err != nil {
fmt.Printf("Error parsing flags: %s\n", err)
c.usage()
os.Exit(1)
}
if !c.CheckFlags() {
fmt.Println()
c.usage()
os.Exit(1)
}
c.Do()
}
func main() {
if len(os.Args) < 2 {
fmt.Printf("Error: Please supply a sub-command. Usage:\n\n")
usage()
os.Exit(1)
}
cmdName := os.Args[1]
for _, cmd := range commands {
if cmd.Name == cmdName {
runCmd(&cmd)
os.Exit(0)
}
}
switch cmdName {
case "-h", "-help", "--help", "help":
usage()
default:
fmt.Println("Error: Invalid sub-command. Usage:")
usage()
os.Exit(1)
}
}
================================================
FILE: cmd/ofx/profiledownload.go
================================================
package main
import (
"flag"
"fmt"
"github.com/aclindsa/ofxgo"
"io"
"os"
)
var profileDownloadCommand = command{
Name: "download-profile",
Description: "Download a FI profile to a file",
Flags: flag.NewFlagSet("download-profile", flag.ExitOnError),
CheckFlags: downloadProfileCheckFlags,
Do: downloadProfile,
}
func init() {
defineServerFlags(profileDownloadCommand.Flags)
profileDownloadCommand.Flags.StringVar(&filename, "filename", "./response.ofx", "The file to save to")
}
func downloadProfileCheckFlags() bool {
// Assume if the user didn't specify username that we should use anonymous
// values for it and password
if len(username) == 0 {
username = "anonymous00000000000000000000000"
password = "anonymous00000000000000000000000"
}
ret := checkServerFlags()
if len(filename) == 0 {
fmt.Println("Error: Filename empty")
return false
}
return ret
}
func downloadProfile() {
client, query := newRequest()
uid, err := ofxgo.RandomUID()
if err != nil {
fmt.Println("Error creating uid for transaction:", err)
os.Exit(1)
}
profileRequest := ofxgo.ProfileRequest{
TrnUID: *uid,
}
query.Prof = append(query.Prof, &profileRequest)
if dryrun {
printRequest(client, query)
return
}
response, err := client.RequestNoParse(query)
if err != nil {
fmt.Println("Error requesting FI profile:", err)
os.Exit(1)
}
defer response.Body.Close()
file, err := os.Create(filename)
if err != nil {
fmt.Println("Error creating file to write to:", err)
os.Exit(1)
}
defer file.Close()
_, err = io.Copy(file, response.Body)
if err != nil {
fmt.Println("Error writing response to file:", err)
os.Exit(1)
}
}
================================================
FILE: cmd/ofx/util.go
================================================
package main
import (
"fmt"
"github.com/aclindsa/ofxgo"
"os"
)
func newRequest() (ofxgo.Client, *ofxgo.Request) {
ver, err := ofxgo.NewOfxVersion(ofxVersion)
if err != nil {
fmt.Println("Error creating new OfxVersion enum:", err)
os.Exit(1)
}
var client = ofxgo.GetClient(serverURL,
&ofxgo.BasicClient{
AppID: appID,
AppVer: appVer,
SpecVersion: ver,
NoIndent: noIndentRequests,
CarriageReturn: carriageReturn,
UserAgent: userAgent,
})
var query ofxgo.Request
query.URL = serverURL
query.Signon.ClientUID = ofxgo.UID(clientUID)
query.Signon.UserID = ofxgo.String(username)
query.Signon.UserPass = ofxgo.String(password)
query.Signon.Org = ofxgo.String(org)
query.Signon.Fid = ofxgo.String(fid)
return client, &query
}
func printRequest(c ofxgo.Client, r *ofxgo.Request) {
r.SetClientFields(c)
b, err := r.Marshal()
if err != nil {
fmt.Println(err)
return
}
fmt.Println(b)
}
================================================
FILE: common.go
================================================
package ofxgo
//go:generate ./generate_constants.py
import (
"bytes"
"errors"
"fmt"
"strings"
"github.com/aclindsa/xml"
)
func writeHeader(b *bytes.Buffer, v ofxVersion, carriageReturn bool) error {
// Write the header appropriate to our version
switch v {
case OfxVersion102, OfxVersion103, OfxVersion151, OfxVersion160:
header := `OFXHEADER:100
DATA:OFXSGML
VERSION:` + v.String() + `
SECURITY:NONE
ENCODING:USASCII
CHARSET:1252
COMPRESSION:NONE
OLDFILEUID:NONE
NEWFILEUID:NONE
`
if carriageReturn {
header = strings.Replace(header, "\n", "\r\n", -1)
}
b.WriteString(header)
case OfxVersion200, OfxVersion201, OfxVersion202, OfxVersion203, OfxVersion210, OfxVersion211, OfxVersion220:
b.WriteString(`<?xml version="1.0" encoding="UTF-8" standalone="no"?>`)
if carriageReturn {
b.WriteByte('\r')
}
b.WriteByte('\n')
b.WriteString(`<?OFX OFXHEADER="200" VERSION="` + v.String() + `" SECURITY="NONE" OLDFILEUID="NONE" NEWFILEUID="NONE"?>`)
if carriageReturn {
b.WriteByte('\r')
}
b.WriteByte('\n')
default:
return fmt.Errorf("%d is not a valid OFX version string", v)
}
return nil
}
// Message represents an OFX message in a message set. it is used to ease
// marshalling and unmarshalling.
type Message interface {
Name() string // The name of the OFX transaction wrapper element this represents
Valid(version ofxVersion) (bool, error) // Called before a Message is marshaled and after it's unmarshaled to ensure the request or response is valid
Type() messageType // The message set this message belongs to
}
type messageType uint
// These constants are returned by Messages' Type() functions to determine
// which message set they belong to
const (
// Requests
SignonRq messageType = iota
SignupRq
BankRq
CreditCardRq
LoanRq
InvStmtRq
InterXferRq
WireXferRq
BillpayRq
EmailRq
SecListRq
PresDirRq
PresDlvRq
ProfRq
ImageRq
// Responses
SignonRs
SignupRs
BankRs
CreditCardRs
LoanRs
InvStmtRs
InterXferRs
WireXferRs
BillpayRs
EmailRs
SecListRs
PresDirRs
PresDlvRs
ProfRs
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 ProfRq:
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 ProfRs:
return "PROFMSGSRSV1"
case ImageRs:
return "IMAGEMSGSRSV1"
}
panic("Invalid messageType")
}
// Map of error codes to their meanings, SEVERITY, and conditions under which
// OFX servers are expected to return them
var statusMeanings = map[Int][3]string{
0: {"Success", "INFO", "The server successfully processed the request."},
1: {"Client is up-to-date", "INFO", "Based on the client timestamp, the client has the latest information. The response does not supply any additional information."},
2000: {"General error", "ERROR", "Error other than those specified by the remaining error codes. Note: Servers should provide a more specific error whenever possible. Error code 2000 should be reserved for cases in which a more specific code is not available."},
2001: {"Invalid account", "ERROR", ""},
2002: {"General account error", "ERROR", "Account error not specified by the remaining error codes."},
2003: {"Account not found", "ERROR", "The specified account number does not correspond to one of the user’s accounts."},
2004: {"Account closed", "ERROR", "The specified account number corresponds to an account that has been closed."},
2005: {"Account not authorized", "ERROR", "The user is not authorized to perform this action on the account, or the server does not allow this type of action to be performed on the account."},
2006: {"Source account not found", "ERROR", "The specified account number does not correspond to one of the user’s accounts."},
2007: {"Source account closed", "ERROR", "The specified account number corresponds to an account that has been closed."},
2008: {"Source account not authorized", "ERROR", "The user is not authorized to perform this action on the account, or the server does not allow this type of action to be performed on the account."},
2009: {"Destination account not found", "ERROR", "The specified account number does not correspond to one of the user’s accounts."},
2010: {"Destination account closed", "ERROR", "The specified account number corresponds to an account that has been closed."},
2011: {"Destination account not authorized", "ERROR", "The user is not authorized to perform this action on the account, or the server does not allow this type of action to be performed on the account."},
2012: {"Invalid amount", "ERROR", "The specified amount is not valid for this action; for example, the user specified a negative payment amount."},
2014: {"Date too soon", "ERROR", "The server cannot process the requested action by the date specified by the user."},
2015: {"Date too far in future", "ERROR", "The server cannot accept requests for an action that far in the future."},
2016: {"Transaction already committed", "ERROR", "Transaction has entered the processing loop and cannot be modified/cancelled using OFX. The transaction may still be cancelled or modified using other means (for example, a phone call to Customer Service)."},
2017: {"Already canceled", "ERROR", "The transaction cannot be canceled or modified because it has already been canceled."},
2018: {"Unknown server ID", "ERROR", "The specified server ID does not exist or no longer exists."},
2019: {"Duplicate request", "ERROR", "A request with this <TRNUID> has already been received and processed."},
2020: {"Invalid date", "ERROR", "The specified datetime stamp cannot be parsed; for instance, the datetime stamp specifies 25:00 hours."},
2021: {"Unsupported version", "ERROR", "The server does not support the requested version. The version of the message set specified by the client is not supported by this server."},
2022: {"Invalid TAN", "ERROR", "The server was unable to validate the TAN sent in the request."},
2023: {"Unknown FITID", "ERROR", "The specified FITID/BILLID does not exist or no longer exists. [BILLID not found (ERROR) in the billing message sets]"},
2025: {"Branch ID missing", "ERROR", "A <BRANCHID> value must be provided in the <BANKACCTFROM> aggregate for this country system, but this field is missing."},
2026: {"Bank name doesn’t match bank ID", "ERROR", "The value of <BANKNAME> in the <EXTBANKACCTTO> aggregate is inconsistent with the value of <BANKID> in the <BANKACCTTO> aggregate."},
2027: {"Invalid date range", "ERROR", "Response for non-overlapping dates, date ranges in the future, et cetera."},
2028: {"Requested element unknown", "WARN", "One or more elements of the request were not recognized by the server or the server (as noted in the FI Profile) does not support the elements. The server executed the element transactions it understood and supported. For example, the request file included private tags in a <PMTRQ> but the server was able to execute the rest of the request."},
3000: {"MFA Challenge authentication required", "ERROR", "User credentials are correct, but further authentication required. Client should send <MFACHALLENGERQ> in next request."},
3001: {"MFA Challenge information is invalid", "ERROR", "User or client information sent in MFACHALLENGEA contains invalid information"},
6500: {"<REJECTIFMISSING>Y invalid without <TOKEN>", "ERROR", "This error code may appear in the <SYNCERROR> element of an <xxxSYNCRS> wrapper (in <PRESDLVMSGSRSV1> and V2 message set responses) or the <CODE> contained in any embedded transaction wrappers within a sync response. The corresponding sync request wrapper included <REJECTIFMISSING>Y with <REFRESH>Y or <TOKENONLY>Y, which is illegal."},
6501: {"Embedded transactions in request failed to process: Out of date", "WARN", "<REJECTIFMISSING>Y and embedded transactions appeared in the request sync wrapper and the provided <TOKEN> was out of date. This code should be used in the <SYNCERROR> of the response sync wrapper."},
6502: {"Unable to process embedded transaction due to out-of-date <TOKEN>", "ERROR", "Used in response transaction wrapper for embedded transactions when <SYNCERROR>6501 appears in the surrounding sync wrapper."},
10000: {"Stop check in process", "INFO", "Stop check is already in process."},
10500: {"Too many checks to process", "ERROR", "The stop-payment request <STPCHKRQ> specifies too many checks."},
10501: {"Invalid payee", "ERROR", "Payee error not specified by the remaining error codes."},
10502: {"Invalid payee address", "ERROR", "Some portion of the payee’s address is incorrect or unknown."},
10503: {"Invalid payee account number", "ERROR", "The account number <PAYACCT> of the requested payee is invalid."},
10504: {"Insufficient funds", "ERROR", "The server cannot process the request because the specified account does not have enough funds."},
10505: {"Cannot modify element", "ERROR", "The server does not allow modifications to one or more values in a modification request."},
10506: {"Cannot modify source account", "ERROR", "Reserved for future use."},
10507: {"Cannot modify destination account", "ERROR", "Reserved for future use."},
10508: {"Invalid frequency", "ERROR", "The specified frequency <FREQ> does not match one of the accepted frequencies for recurring transactions."},
10509: {"Model already canceled", "ERROR", "The server has already canceled the specified recurring model."},
10510: {"Invalid payee ID", "ERROR", "The specified payee ID does not exist or no longer exists."},
10511: {"Invalid payee city", "ERROR", "The specified city is incorrect or unknown."},
10512: {"Invalid payee state", "ERROR", "The specified state is incorrect or unknown."},
10513: {"Invalid payee postal code", "ERROR", "The specified postal code is incorrect or unknown."},
10514: {"Transaction already processed", "ERROR", "Transaction has already been sent or date due is past"},
10515: {"Payee not modifiable by client", "ERROR", "The server does not allow clients to change payee information."},
10516: {"Wire beneficiary invalid", "ERROR", "The specified wire beneficiary does not exist or no longer exists."},
10517: {"Invalid payee name", "ERROR", "The server does not recognize the specified payee name."},
10518: {"Unknown model ID", "ERROR", "The specified model ID does not exist or no longer exists."},
10519: {"Invalid payee list ID", "ERROR", "The specified payee list ID does not exist or no longer exists."},
10600: {"Table type not found", "ERROR", "The specified table type is not recognized or does not exist."},
12250: {"Investment transaction download not supported", "WARN", "The server does not support investment transaction download."},
12251: {"Investment position download not supported", "WARN", "The server does not support investment position download."},
12252: {"Investment positions for specified date not available", "WARN", "The server does not support investment positions for the specified date."},
12253: {"Investment open order download not supported", "WARN", "The server does not support open order download."},
12254: {"Investment balances download not supported", "WARN", "The server does not support investment balances download."},
12255: {"401(k) not available for this account", "ERROR", "401(k) information requested from a non- 401(k) account."},
12500: {"One or more securities not found", "ERROR", "The server could not find the requested securities."},
13000: {"User ID & password will be sent out-of-band", "INFO", "The server will send the user ID and password via postal mail, e-mail, or another means. The accompanying message will provide details."},
13500: {"Unable to enroll user", "ERROR", "The server could not enroll the user."},
13501: {"User already enrolled", "ERROR", "The server has already enrolled the user."},
13502: {"Invalid service", "ERROR", "The server does not support the service <SVC> specified in the service-activation request."},
13503: {"Cannot change user information", "ERROR", "The server does not support the <CHGUSERINFORQ> request."},
13504: {"<FI> Missing or Invalid in <SONRQ>", "ERROR", "The FI requires the client to provide the <FI> aggregate in the <SONRQ> request, but either none was provided, or the one provided was invalid."},
14500: {"1099 forms not available", "ERROR", "1099 forms are not yet available for the tax year requested."},
14501: {"1099 forms not available for user ID", "ERROR", "This user does not have any 1099 forms available."},
14600: {"W2 forms not available", "ERROR", "W2 forms are not yet available for the tax year requested."},
14601: {"W2 forms not available for user ID", "ERROR", "The user does not have any W2 forms available."},
14700: {"1098 forms not available", "ERROR", "1098 forms are not yet available for the tax year requested."},
14701: {"1098 forms not available for user ID", "ERROR", "The user does not have any 1098 forms available."},
15000: {"Must change USERPASS", "INFO", "The user must change his or her <USERPASS> number as part of the next OFX request."},
15500: {"Signon invalid", "ERROR", "The user cannot signon because he or she entered an invalid user ID or password."},
15501: {"Customer account already in use", "ERROR", "The server allows only one connection at a time, and another user is already signed on. Please try again later."},
15502: {"USERPASS lockout", "ERROR", "The server has received too many failed signon attempts for this user. Please call the FI’s technical support number."},
15503: {"Could not change USERPASS", "ERROR", "The server does not support the <PINCHRQ> request."},
15504: {"Could not provide random data", "ERROR", "The server could not generate random data as requested by the <CHALLENGERQ>."},
15505: {"Country system not supported", "ERROR", "The server does not support the country specified in the <COUNTRY> field of the <SONRQ> aggregate."},
15506: {"Empty signon not supported", "ERROR", "The server does not support signons not accompanied by some other transaction."},
15507: {"Signon invalid without supporting pin change request", "ERROR", "The OFX block associated with the signon does not contain a pin change request and should."},
15508: {"Transaction not authorized. ", "ERROR", "Current user is not authorized to perform this action on behalf of the <USERID>."},
15510: {"CLIENTUID error", "ERROR", "The CLIENTUID sent by the client was incorrect. User must register the Client UID."},
15511: {"MFA error", "ERROR", "User should contact financial institution."},
15512: {"AUTHTOKEN required", "ERROR", "User needs to contact financial institution to obtain AUTHTOKEN. Client should send it in the next request."},
15513: {"AUTHTOKEN invalid", "ERROR", "The AUTHTOKEN sent by the client was invalid."},
16500: {"HTML not allowed", "ERROR", "The server does not accept HTML formatting in the request."},
16501: {"Unknown mail To:", "ERROR", "The server was unable to send mail to the specified Internet address."},
16502: {"Invalid URL", "ERROR", "The server could not parse the URL."},
16503: {"Unable to get URL", "ERROR", "The server was unable to retrieve the information at this URL (e.g., an HTTP 400 or 500 series error)."},
}
// Status represents the status of a Response (both top-level Request objects,
// and *Response objects)
type Status struct {
XMLName xml.Name `xml:"STATUS"`
Code Int `xml:"CODE"`
Severity String `xml:"SEVERITY"`
Message String `xml:"MESSAGE,omitempty"`
}
// Valid returns whether the Status is valid according to the OFX spec
func (s *Status) Valid() (bool, error) {
switch s.Severity {
case "INFO", "WARN", "ERROR":
default:
return false, errors.New("Invalid STATUS>SEVERITY")
}
if arr, ok := statusMeanings[s.Code]; ok {
if arr[1] != string(s.Severity) {
return false, errors.New("Unexpected SEVERITY for STATUS>CODE")
}
} else {
return false, errors.New("Unknown OFX status code")
}
return true, nil
}
// CodeMeaning returns the meaning of the current status Code
func (s *Status) CodeMeaning() (string, error) {
if arr, ok := statusMeanings[s.Code]; ok {
return arr[0], nil
}
return "", errors.New("Unknown OFX status code")
}
// CodeConditions returns the conditions under which an OFX server is expected
// to return the current status Code
func (s *Status) CodeConditions() (string, error) {
if arr, ok := statusMeanings[s.Code]; ok {
return arr[2], nil
}
return "", errors.New("Unknown OFX status code")
}
// BankAcct represents the identifying information for one bank account
type BankAcct struct {
XMLName xml.Name // BANKACCTTO or BANKACCTFROM
BankID String `xml:"BANKID"`
BranchID String `xml:"BRANCHID,omitempty"` // Unused in USA
AcctID String `xml:"ACCTID"`
AcctType acctType `xml:"ACCTTYPE"` // One of CHECKING, SAVINGS, MONEYMRKT, CREDITLINE, CD
AcctKey String `xml:"ACCTKEY,omitempty"` // Unused in USA
}
// Valid returns whether the BankAcct is valid according to the OFX spec
func (b BankAcct) Valid() (bool, error) {
if len(b.BankID) == 0 {
return false, errors.New("BankAcct.BankID empty")
}
if len(b.AcctID) == 0 {
return false, errors.New("BankAcct.AcctID empty")
}
if !b.AcctType.Valid() {
return false, errors.New("Invalid or unspecified BankAcct.AcctType")
}
return true, nil
}
// CCAcct represents the identifying information for one checking account
type CCAcct struct {
XMLName xml.Name // CCACCTTO or CCACCTFROM
AcctID String `xml:"ACCTID"`
AcctKey String `xml:"ACCTKEY,omitempty"` // Unused in USA
}
// Valid returns whether the CCAcct is valid according to the OFX spec
func (c CCAcct) Valid() (bool, error) {
if len(c.AcctID) == 0 {
return false, errors.New("CCAcct.AcctID empty")
}
return true, nil
}
// InvAcct represents the identifying information for one investment account
type InvAcct struct {
XMLName xml.Name // INVACCTTO or INVACCTFROM
BrokerID String `xml:"BROKERID"`
AcctID String `xml:"ACCTID"`
}
// Currency represents one ISO-4217 currency. CURRENCY elements signify that
// the transaction containing this Currency struct is in this currency instead
// of being converted to the statement's default. ORIGCURRENCY elements signify
// that the transaction containing this Currency struct was converted to the
// statement's default from the specified currency.
type Currency struct {
XMLName xml.Name // CURRENCY or ORIGCURRENCY
CurRate Amount `xml:"CURRATE"` // Ratio of statement's currency (CURDEF) to transaction currency (CURSYM)
CurSym CurrSymbol `xml:"CURSYM"` // ISO-4217 3-character currency identifier
}
// Valid returns whether the Currency is valid according to the OFX spec
func (c Currency) Valid() (bool, error) {
if c.CurRate.IsInt() && c.CurRate.Num().Int64() == 0 {
return false, errors.New("CurRate may not be zero")
} else if ok, err := c.CurSym.Valid(); !ok {
return false, err
}
return true, nil
}
================================================
FILE: common_test.go
================================================
package ofxgo
import (
"testing"
)
func TestStatusValid(t *testing.T) {
s := Status{
Code: 0,
Severity: "INFO",
Message: "Success",
}
if ok, err := s.Valid(); !ok {
t.Fatalf("Status unexpectedly invalid: %s\n", err)
}
s.Severity = "INVALID"
if ok, err := s.Valid(); ok || err == nil {
t.Fatalf("Status unexpectedly valid invalid Severity\n")
}
s.Severity = "WARN"
if ok, err := s.Valid(); ok || err == nil {
t.Fatalf("Status unexpectedly valid with wrong Severity for Code 0\n")
}
s.Code = 9
if ok, err := s.Valid(); ok || err == nil {
t.Fatalf("Status unexpectedly valid with invalid Code\n")
}
}
func TestStatusCodeMeaning(t *testing.T) {
s := Status{
Code: 15500,
Severity: "ERROR",
}
meaning, err := s.CodeMeaning()
if err != nil {
t.Fatalf("Status.CodeMeaning unexpectedly failed: %s\n", err)
}
if meaning != "Signon invalid" {
t.Fatalf("Unexpected meaning for Code 15500: \"%s\"\n", meaning)
}
s.Code = 999
if meaning, err := s.CodeMeaning(); len(meaning) != 0 || err == nil {
t.Fatalf("Status.CodeMeaning unexpectedly succeeded with invalid Code\n")
}
}
func TestStatusCodeConditions(t *testing.T) {
s := Status{
Code: 2006,
Severity: "ERROR",
}
if conditions, err := s.CodeConditions(); len(conditions) == 0 || err != nil {
t.Fatalf("Status.CodeConditions unexpectedly failed: %s\n", err)
}
s.Code = 999
if conditions, err := s.CodeConditions(); len(conditions) != 0 || err == nil {
t.Fatalf("Status.CodeConditions unexpectedly succeeded with invalid Code\n")
}
}
================================================
FILE: constants.go
================================================
package ofxgo
/*
* Do not edit this file by hand. It is auto-generated by calling `go generate`.
* To make changes, edit generate_constants.py, re-run `go generate`, and check
* in the result.
*/
import (
"errors"
"fmt"
"strings"
"github.com/aclindsa/xml"
)
type ofxVersion uint
// OfxVersion* constants represent the OFX specification version in use
const (
OfxVersion102 ofxVersion = 1 + iota
OfxVersion103
OfxVersion151
OfxVersion160
OfxVersion200
OfxVersion201
OfxVersion202
OfxVersion203
OfxVersion210
OfxVersion211
OfxVersion220
)
var ofxVersions = [...]string{"102", "103", "151", "160", "200", "201", "202", "203", "210", "211", "220"}
func (e ofxVersion) Valid() bool {
// This check is mostly out of paranoia, ensuring e != 0 should be
// sufficient
return e >= OfxVersion102 && e <= OfxVersion220
}
func (e ofxVersion) String() string {
if e.Valid() {
return ofxVersions[e-1]
}
return fmt.Sprintf("invalid ofxVersion (%d)", e)
}
func (e *ofxVersion) FromString(in string) error {
value := strings.TrimSpace(in)
for i, s := range ofxVersions {
if s == value {
*e = ofxVersion(i + 1)
return nil
}
}
*e = 0
return errors.New("Invalid OfxVersion: \"" + in + "\"")
}
func (e *ofxVersion) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var value string
err := d.DecodeElement(&value, &start)
if err != nil {
return err
}
return e.FromString(value)
}
func (e ofxVersion) MarshalXML(enc *xml.Encoder, start xml.StartElement) error {
if !e.Valid() {
return nil
}
enc.EncodeElement(ofxVersions[e-1], start)
return nil
}
// NewOfxVersion returns returns an 'enum' value of type ofxVersion given its
// string representation
func NewOfxVersion(s string) (ofxVersion, error) {
var e ofxVersion
err := e.FromString(s)
if err != nil {
return 0, err
}
return e, nil
}
type acctType uint
// AcctType* constants represent types of bank accounts
const (
AcctTypeChecking acctType = 1 + iota
AcctTypeSavings
AcctTypeMoneyMrkt
AcctTypeCreditLine
AcctTypeCD
)
var acctTypes = [...]string{"CHECKING", "SAVINGS", "MONEYMRKT", "CREDITLINE", "CD"}
func (e acctType) Valid() bool {
// This check is mostly out of paranoia, ensuring e != 0 should be
// sufficient
return e >= AcctTypeChecking && e <= AcctTypeCD
}
func (e acctType) String() string {
if e.Valid() {
return acctTypes[e-1]
}
return fmt.Sprintf("invalid acctType (%d)", e)
}
func (e *acctType) FromString(in string) error {
value := strings.TrimSpace(in)
for i, s := range acctTypes {
if s == value {
*e = acctType(i + 1)
return nil
}
}
*e = 0
return errors.New("Invalid AcctType: \"" + in + "\"")
}
func (e *acctType) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var value string
err := d.DecodeElement(&value, &start)
if err != nil {
return err
}
return e.FromString(value)
}
func (e acctType) MarshalXML(enc *xml.Encoder, start xml.StartElement) error {
if !e.Valid() {
return nil
}
enc.EncodeElement(acctTypes[e-1], start)
return nil
}
// NewAcctType returns returns an 'enum' value of type acctType given its
// string representation
func NewAcctType(s string) (acctType, error) {
var e acctType
err := e.FromString(s)
if err != nil {
return 0, err
}
return e, nil
}
type trnType uint
// TrnType* constants represent types of transactions. INT, ATM, and POS depend on the signage of the account.
const (
TrnTypeCredit trnType = 1 + iota
TrnTypeDebit
TrnTypeInt
TrnTypeDiv
TrnTypeFee
TrnTypeSrvChg
TrnTypeDep
TrnTypeATM
TrnTypePOS
TrnTypeXfer
TrnTypeCheck
TrnTypePayment
TrnTypeCash
TrnTypeDirectDep
TrnTypeDirectDebit
TrnTypeRepeatPmt
TrnTypeHold
TrnTypeOther
)
var trnTypes = [...]string{"CREDIT", "DEBIT", "INT", "DIV", "FEE", "SRVCHG", "DEP", "ATM", "POS", "XFER", "CHECK", "PAYMENT", "CASH", "DIRECTDEP", "DIRECTDEBIT", "REPEATPMT", "HOLD", "OTHER"}
func (e trnType) Valid() bool {
// This check is mostly out of paranoia, ensuring e != 0 should be
// sufficient
return e >= TrnTypeCredit && e <= TrnTypeOther
}
func (e trnType) String() string {
if e.Valid() {
return trnTypes[e-1]
}
return fmt.Sprintf("invalid trnType (%d)", e)
}
func (e *trnType) FromString(in string) error {
value := strings.TrimSpace(in)
for i, s := range trnTypes {
if s == value {
*e = trnType(i + 1)
return nil
}
}
*e = 0
return errors.New("Invalid TrnType: \"" + in + "\"")
}
func (e *trnType) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var value string
err := d.DecodeElement(&value, &start)
if err != nil {
return err
}
return e.FromString(value)
}
func (e trnType) MarshalXML(enc *xml.Encoder, start xml.StartElement) error {
if !e.Valid() {
return nil
}
enc.EncodeElement(trnTypes[e-1], start)
return nil
}
// NewTrnType returns returns an 'enum' value of type trnType given its
// string representation
func NewTrnType(s string) (trnType, error) {
var e trnType
err := e.FromString(s)
if err != nil {
return 0, err
}
return e, nil
}
type imageType uint
// ImageType* constants represent what this image contains
const (
ImageTypeStatement imageType = 1 + iota
ImageTypeTransaction
ImageTypeTax
)
var imageTypes = [...]string{"STATEMENT", "TRANSACTION", "TAX"}
func (e imageType) Valid() bool {
// This check is mostly out of paranoia, ensuring e != 0 should be
// sufficient
return e >= ImageTypeStatement && e <= ImageTypeTax
}
func (e imageType) String() string {
if e.Valid() {
return imageTypes[e-1]
}
return fmt.Sprintf("invalid imageType (%d)", e)
}
func (e *imageType) FromString(in string) error {
value := strings.TrimSpace(in)
for i, s := range imageTypes {
if s == value {
*e = imageType(i + 1)
return nil
}
}
*e = 0
return errors.New("Invalid ImageType: \"" + in + "\"")
}
func (e *imageType) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var value string
err := d.DecodeElement(&value, &start)
if err != nil {
return err
}
return e.FromString(value)
}
func (e imageType) MarshalXML(enc *xml.Encoder, start xml.StartElement) error {
if !e.Valid() {
return nil
}
enc.EncodeElement(imageTypes[e-1], start)
return nil
}
// NewImageType returns returns an 'enum' value of type imageType given its
// string representation
func NewImageType(s string) (imageType, error) {
var e imageType
err := e.FromString(s)
if err != nil {
return 0, err
}
return e, nil
}
type imageRefType uint
// ImageRefType* constants represent the type of reference to the image
const (
ImageRefTypeOpaque imageRefType = 1 + iota
ImageRefTypeURL
ImageRefTypeFormURL
)
var imageRefTypes = [...]string{"OPAQUE", "URL", "FORMURL"}
func (e imageRefType) Valid() bool {
// This check is mostly out of paranoia, ensuring e != 0 should be
// sufficient
return e >= ImageRefTypeOpaque && e <= ImageRefTypeFormURL
}
func (e imageRefType) String() string {
if e.Valid() {
return imageRefTypes[e-1]
}
return fmt.Sprintf("invalid imageRefType (%d)", e)
}
func (e *imageRefType) FromString(in string) error {
value := strings.TrimSpace(in)
for i, s := range imageRefTypes {
if s == value {
*e = imageRefType(i + 1)
return nil
}
}
*e = 0
return errors.New("Invalid ImageRefType: \"" + in + "\"")
}
func (e *imageRefType) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var value string
err := d.DecodeElement(&value, &start)
if err != nil {
return err
}
return e.FromString(value)
}
func (e imageRefType) MarshalXML(enc *xml.Encoder, start xml.StartElement) error {
if !e.Valid() {
return nil
}
enc.EncodeElement(imageRefTypes[e-1], start)
return nil
}
// NewImageRefType returns returns an 'enum' value of type imageRefType given its
// string representation
func NewImageRefType(s string) (imageRefType, error) {
var e imageRefType
err := e.FromString(s)
if err != nil {
return 0, err
}
return e, nil
}
type checkSup uint
// CheckSup* constants represent what portions of the check this image contains
const (
CheckSupFrontOnly checkSup = 1 + iota
CheckSupBackOnly
CheckSupFrontAndBack
)
var checkSups = [...]string{"FRONTONLY", "BACKONLY", "FRONTANDBACK"}
func (e checkSup) Valid() bool {
// This check is mostly out of paranoia, ensuring e != 0 should be
// sufficient
return e >= CheckSupFrontOnly && e <= CheckSupFrontAndBack
}
func (e checkSup) String() string {
if e.Valid() {
return checkSups[e-1]
}
return fmt.Sprintf("invalid checkSup (%d)", e)
}
func (e *checkSup) FromString(in string) error {
value := strings.TrimSpace(in)
for i, s := range checkSups {
if s == value {
*e = checkSup(i + 1)
return nil
}
}
*e = 0
return errors.New("Invalid CheckSup: \"" + in + "\"")
}
func (e *checkSup) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var value string
err := d.DecodeElement(&value, &start)
if err != nil {
return err
}
return e.FromString(value)
}
func (e checkSup) MarshalXML(enc *xml.Encoder, start xml.StartElement) error {
if !e.Valid() {
return nil
}
enc.EncodeElement(checkSups[e-1], start)
return nil
}
// NewCheckSup returns returns an 'enum' value of type checkSup given its
// string representation
func NewCheckSup(s string) (checkSup, error) {
var e checkSup
err := e.FromString(s)
if err != nil {
return 0, err
}
return e, nil
}
type correctAction uint
// CorrectAction* constants represent whether this transaction correction replaces or deletes the transaction matching its CORRECTFITID
const (
CorrectActionDelete correctAction = 1 + iota
CorrectActionReplace
)
var correctActions = [...]string{"DELETE", "REPLACE"}
func (e correctAction) Valid() bool {
// This check is mostly out of paranoia, ensuring e != 0 should be
// sufficient
return e >= CorrectActionDelete && e <= CorrectActionReplace
}
func (e correctAction) String() string {
if e.Valid() {
return correctActions[e-1]
}
return fmt.Sprintf("invalid correctAction (%d)", e)
}
func (e *correctAction) FromString(in string) error {
value := strings.TrimSpace(in)
for i, s := range correctActions {
if s == value {
*e = correctAction(i + 1)
return nil
}
}
*e = 0
return errors.New("Invalid CorrectAction: \"" + in + "\"")
}
func (e *correctAction) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var value string
err := d.DecodeElement(&value, &start)
if err != nil {
return err
}
return e.FromString(value)
}
func (e correctAction) MarshalXML(enc *xml.Encoder, start xml.StartElement) error {
if !e.Valid() {
return nil
}
enc.EncodeElement(correctActions[e-1], start)
return nil
}
// NewCorrectAction returns returns an 'enum' value of type correctAction given its
// string representation
func NewCorrectAction(s string) (correctAction, error) {
var e correctAction
err := e.FromString(s)
if err != nil {
return 0, err
}
return e, nil
}
type balType uint
// BalType* constants represent how this BAL's VALUE field should be interpreted
const (
BalTypeDollar balType = 1 + iota
BalTypePercent
BalTypeNumber
)
var balTypes = [...]string{"DOLLAR", "PERCENT", "NUMBER"}
func (e balType) Valid() bool {
// This check is mostly out of paranoia, ensuring e != 0 should be
// sufficient
return e >= BalTypeDollar && e <= BalTypeNumber
}
func (e balType) String() string {
if e.Valid() {
return balTypes[e-1]
}
return fmt.Sprintf("invalid balType (%d)", e)
}
func (e *balType) FromString(in string) error {
value := strings.TrimSpace(in)
for i, s := range balTypes {
if s == value {
*e = balType(i + 1)
return nil
}
}
*e = 0
return errors.New("Invalid BalType: \"" + in + "\"")
}
func (e *balType) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var value string
err := d.DecodeElement(&value, &start)
if err != nil {
return err
}
return e.FromString(value)
}
func (e balType) MarshalXML(enc *xml.Encoder, start xml.StartElement) error {
if !e.Valid() {
return nil
}
enc.EncodeElement(balTypes[e-1], start)
return nil
}
// NewBalType returns returns an 'enum' value of type balType given its
// string representation
func NewBalType(s string) (balType, error) {
var e balType
err := e.FromString(s)
if err != nil {
return 0, err
}
return e, nil
}
type inv401kSource uint
// Inv401kSource* constants represent the source of money used for this security in a 401(k) account. Default if not present is OTHERNONVEST. The following cash source types are subject to vesting: MATCH, PROFITSHARING, and OTHERVEST.
const (
Inv401kSourcePreTax inv401kSource = 1 + iota
Inv401kSourceAfterTax
Inv401kSourceMatch
Inv401kSourceProfitSharing
Inv401kSourceRollover
Inv401kSourceOtherVest
Inv401kSourceOtherNonVest
)
var inv401kSources = [...]string{"PRETAX", "AFTERTAX", "MATCH", "PROFITSHARING", "ROLLOVER", "OTHERVEST", "OTHERNONVEST"}
func (e inv401kSource) Valid() bool {
// This check is mostly out of paranoia, ensuring e != 0 should be
// sufficient
return e >= Inv401kSourcePreTax && e <= Inv401kSourceOtherNonVest
}
func (e inv401kSource) String() string {
if e.Valid() {
return inv401kSources[e-1]
}
return fmt.Sprintf("invalid inv401kSource (%d)", e)
}
func (e *inv401kSource) FromString(in string) error {
value := strings.TrimSpace(in)
for i, s := range inv401kSources {
if s == value {
*e = inv401kSource(i + 1)
return nil
}
}
*e = 0
return errors.New("Invalid Inv401kSource: \"" + in + "\"")
}
func (e *inv401kSource) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var value string
err := d.DecodeElement(&value, &start)
if err != nil {
return err
}
return e.FromString(value)
}
func (e inv401kSource) MarshalXML(enc *xml.Encoder, start xml.StartElement) error {
if !e.Valid() {
return nil
}
enc.EncodeElement(inv401kSources[e-1], start)
return nil
}
// NewInv401kSource returns returns an 'enum' value of type inv401kSource given its
// string representation
func NewInv401kSource(s string) (inv401kSource, error) {
var e inv401kSource
err := e.FromString(s)
if err != nil {
return 0, err
}
return e, nil
}
type subAcctType uint
// SubAcctType* constants represent the sub-account type for a source and/or destination of a transaction. Used in fields named SubAcctFrom, SubAcctTo, SubAcctSec, SubAcctFund, HeldInAcct.
const (
SubAcctTypeCash subAcctType = 1 + iota
SubAcctTypeMargin
SubAcctTypeShort
SubAcctTypeOther
)
var subAcctTypes = [...]string{"CASH", "MARGIN", "SHORT", "OTHER"}
func (e subAcctType) Valid() bool {
// This check is mostly out of paranoia, ensuring e != 0 should be
// sufficient
return e >= SubAcctTypeCash && e <= SubAcctTypeOther
}
func (e subAcctType) String() string {
if e.Valid() {
return subAcctTypes[e-1]
}
return fmt.Sprintf("invalid subAcctType (%d)", e)
}
func (e *subAcctType) FromString(in string) error {
value := strings.TrimSpace(in)
for i, s := range subAcctTypes {
if s == value {
*e = subAcctType(i + 1)
return nil
}
}
*e = 0
return errors.New("Invalid SubAcctType: \"" + in + "\"")
}
func (e *subAcctType) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var value string
err := d.DecodeElement(&value, &start)
if err != nil {
return err
}
return e.FromString(value)
}
func (e subAcctType) MarshalXML(enc *xml.Encoder, start xml.StartElement) error {
if !e.Valid() {
return nil
}
enc.EncodeElement(subAcctTypes[e-1], start)
return nil
}
// NewSubAcctType returns returns an 'enum' value of type subAcctType given its
// string representation
func NewSubAcctType(s string) (subAcctType, error) {
var e subAcctType
err := e.FromString(s)
if err != nil {
return 0, err
}
return e, nil
}
type buyType uint
// BuyType* constants represent types of purchases
const (
BuyTypeBuy buyType = 1 + iota
BuyTypeBuyToCover
)
var buyTypes = [...]string{"BUY", "BUYTOCOVER"}
func (e buyType) Valid() bool {
// This check is mostly out of paranoia, ensuring e != 0 should be
// sufficient
return e >= BuyTypeBuy && e <= BuyTypeBuyToCover
}
func (e buyType) String() string {
if e.Valid() {
return buyTypes[e-1]
}
return fmt.Sprintf("invalid buyType (%d)", e)
}
func (e *buyType) FromString(in string) error {
value := strings.TrimSpace(in)
for i, s := range buyTypes {
if s == value {
*e = buyType(i + 1)
return nil
}
}
*e = 0
return errors.New("Invalid BuyType: \"" + in + "\"")
}
func (e *buyType) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var value string
err := d.DecodeElement(&value, &start)
if err != nil {
return err
}
return e.FromString(value)
}
func (e buyType) MarshalXML(enc *xml.Encoder, start xml.StartElement) error {
if !e.Valid() {
return nil
}
enc.EncodeElement(buyTypes[e-1], start)
return nil
}
// NewBuyType returns returns an 'enum' value of type buyType given its
// string representation
func NewBuyType(s string) (buyType, error) {
var e buyType
err := e.FromString(s)
if err != nil {
return 0, err
}
return e, nil
}
type optAction uint
// OptAction* constants represent types of actions for options
const (
OptActionExercise optAction = 1 + iota
OptActionAssign
OptActionExpire
)
var optActions = [...]string{"EXERCISE", "ASSIGN", "EXPIRE"}
func (e optAction) Valid() bool {
// This check is mostly out of paranoia, ensuring e != 0 should be
// sufficient
return e >= OptActionExercise && e <= OptActionExpire
}
func (e optAction) String() string {
if e.Valid() {
return optActions[e-1]
}
return fmt.Sprintf("invalid optAction (%d)", e)
}
func (e *optAction) FromString(in string) error {
value := strings.TrimSpace(in)
for i, s := range optActions {
if s == value {
*e = optAction(i + 1)
return nil
}
}
*e = 0
return errors.New("Invalid OptAction: \"" + in + "\"")
}
func (e *optAction) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var value string
err := d.DecodeElement(&value, &start)
if err != nil {
return err
}
return e.FromString(value)
}
func (e optAction) MarshalXML(enc *xml.Encoder, start xml.StartElement) error {
if !e.Valid() {
return nil
}
enc.EncodeElement(optActions[e-1], start)
return nil
}
// NewOptAction returns returns an 'enum' value of type optAction given its
// string representation
func NewOptAction(s string) (optAction, error) {
var e optAction
err := e.FromString(s)
if err != nil {
return 0, err
}
return e, nil
}
type tferAction uint
// TferAction* constants represent whether the transfer is into or out of this account
const (
TferActionIn tferAction = 1 + iota
TferActionOut
)
var tferActions = [...]string{"IN", "OUT"}
func (e tferAction) Valid() bool {
// This check is mostly out of paranoia, ensuring e != 0 should be
// sufficient
return e >= TferActionIn && e <= TferActionOut
}
func (e tferAction) String() string {
if e.Valid() {
return tferActions[e-1]
}
return fmt.Sprintf("invalid tferAction (%d)", e)
}
func (e *tferAction) FromString(in string) error {
value := strings.TrimSpace(in)
for i, s := range tferActions {
if s == value {
*e = tferAction(i + 1)
return nil
}
}
*e = 0
return errors.New("Invalid TferAction: \"" + in + "\"")
}
func (e *tferAction) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var value string
err := d.DecodeElement(&value, &start)
if err != nil {
return err
}
return e.FromString(value)
}
func (e tferAction) MarshalXML(enc *xml.Encoder, start xml.StartElement) error {
if !e.Valid() {
return nil
}
enc.EncodeElement(tferActions[e-1], start)
return nil
}
// NewTferAction returns returns an 'enum' value of type tferAction given its
// string representation
func NewTferAction(s string) (tferAction, error) {
var e tferAction
err := e.FromString(s)
if err != nil {
return 0, err
}
return e, nil
}
type posType uint
// PosType* constants represent position type
const (
PosTypeLong posType = 1 + iota
PosTypeShort
)
var posTypes = [...]string{"LONG", "SHORT"}
func (e posType) Valid() bool {
// This check is mostly out of paranoia, ensuring e != 0 should be
// sufficient
return e >= PosTypeLong && e <= PosTypeShort
}
func (e posType) String() string {
if e.Valid() {
return posTypes[e-1]
}
return fmt.Sprintf("invalid posType (%d)", e)
}
func (e *posType) FromString(in string) error {
value := strings.TrimSpace(in)
for i, s := range posTypes {
if s == value {
*e = posType(i + 1)
return nil
}
}
*e = 0
return errors.New("Invalid PosType: \"" + in + "\"")
}
func (e *posType) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var value string
err := d.DecodeElement(&value, &start)
if err != nil {
return err
}
return e.FromString(value)
}
func (e posType) MarshalXML(enc *xml.Encoder, start xml.StartElement) error {
if !e.Valid() {
return nil
}
enc.EncodeElement(posTypes[e-1], start)
return nil
}
// NewPosType returns returns an 'enum' value of type posType given its
// string representation
func NewPosType(s string) (posType, error) {
var e posType
err := e.FromString(s)
if err != nil {
return 0, err
}
return e, nil
}
type secured uint
// Secured* constants represent how an option is secured
const (
SecuredNaked secured = 1 + iota
SecuredCovered
)
var secureds = [...]string{"NAKED", "COVERED"}
func (e secured) Valid() bool {
// This check is mostly out of paranoia, ensuring e != 0 should be
// sufficient
return e >= SecuredNaked && e <= SecuredCovered
}
func (e secured) String() string {
if e.Valid() {
return secureds[e-1]
}
return fmt.Sprintf("invalid secured (%d)", e)
}
func (e *secured) FromString(in string) error {
value := strings.TrimSpace(in)
for i, s := range secureds {
if s == value {
*e = secured(i + 1)
return nil
}
}
*e = 0
return errors.New("Invalid Secured: \"" + in + "\"")
}
func (e *secured) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var value string
err := d.DecodeElement(&value, &start)
if err != nil {
return err
}
return e.FromString(value)
}
func (e secured) MarshalXML(enc *xml.Encoder, start xml.StartElement) error {
if !e.Valid() {
return nil
}
enc.EncodeElement(secureds[e-1], start)
return nil
}
// NewSecured returns returns an 'enum' value of type secured given its
// string representation
func NewSecured(s string) (secured, error) {
var e secured
err := e.FromString(s)
if err != nil {
return 0, err
}
return e, nil
}
type duration uint
// Duration* constants represent how long the investment order is good for
const (
DurationDay duration = 1 + iota
DurationGoodTilCancel
DurationImmediate
)
var durations = [...]string{"DAY", "GOODTILCANCEL", "IMMEDIATE"}
func (e duration) Valid() bool {
// This check is mostly out of paranoia, ensuring e != 0 should be
// sufficient
return e >= DurationDay && e <= DurationImmediate
}
func (e duration) String() string {
if e.Valid() {
return durations[e-1]
}
return fmt.Sprintf("invalid duration (%d)", e)
}
func (e *duration) FromString(in string) error {
value := strings.TrimSpace(in)
for i, s := range durations {
if s == value {
*e = duration(i + 1)
return nil
}
}
*e = 0
return errors.New("Invalid Duration: \"" + in + "\"")
}
func (e *duration) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var value string
err := d.DecodeElement(&value, &start)
if err != nil {
return err
}
return e.FromString(value)
}
func (e duration) MarshalXML(enc *xml.Encoder, start xml.StartElement) error {
if !e.Valid() {
return nil
}
enc.EncodeElement(durations[e-1], start)
return nil
}
// NewDuration returns returns an 'enum' value of type duration given its
// string representation
func NewDuration(s string) (duration, error) {
var e duration
err := e.FromString(s)
if err != nil {
return 0, err
}
return e, nil
}
type restriction uint
// Restriction* constants represent a special restriction on an investment order
const (
RestrictionAllOrNone restriction = 1 + iota
RestrictionMinUnits
RestrictionNone
)
var restrictions = [...]string{"ALLORNONE", "MINUNITS", "NONE"}
func (e restriction) Valid() bool {
// This check is mostly out of paranoia, ensuring e != 0 should be
// sufficient
return e >= RestrictionAllOrNone && e <= RestrictionNone
}
func (e restriction) String() string {
if e.Valid() {
return restrictions[e-1]
}
return fmt.Sprintf("invalid restriction (%d)", e)
}
func (e *restriction) FromString(in string) error {
value := strings.TrimSpace(in)
for i, s := range restrictions {
if s == value {
*e = restriction(i + 1)
return nil
}
}
*e = 0
return errors.New("Invalid Restriction: \"" + in + "\"")
}
func (e *restriction) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var value string
err := d.DecodeElement(&value, &start)
if err != nil {
return err
}
return e.FromString(value)
}
func (e restriction) MarshalXML(enc *xml.Encoder, start xml.StartElement) error {
if !e.Valid() {
return nil
}
enc.EncodeElement(restrictions[e-1], start)
return nil
}
// NewRestriction returns returns an 'enum' value of type restriction given its
// string representation
func NewRestriction(s string) (restriction, error) {
var e restriction
err := e.FromString(s)
if err != nil {
return 0, err
}
return e, nil
}
type unitType uint
// UnitType* constants represent type of the UNITS value
const (
UnitTypeShares unitType = 1 + iota
UnitTypeCurrency
)
var unitTypes = [...]string{"SHARES", "CURRENCY"}
func (e unitType) Valid() bool {
// This check is mostly out of paranoia, ensuring e != 0 should be
// sufficient
return e >= UnitTypeShares && e <= UnitTypeCurrency
}
func (e unitType) String() string {
if e.Valid() {
return unitTypes[e-1]
}
return fmt.Sprintf("invalid unitType (%d)", e)
}
func (e *unitType) FromString(in string) error {
value := strings.TrimSpace(in)
for i, s := range unitTypes {
if s == value {
*e = unitType(i + 1)
return nil
}
}
*e = 0
return errors.New("Invalid UnitType: \"" + in + "\"")
}
func (e *unitType) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var value string
err := d.DecodeElement(&value, &start)
if err != nil {
return err
}
return e.FromString(value)
}
func (e unitType) MarshalXML(enc *xml.Encoder, start xml.StartElement) error {
if !e.Valid() {
return nil
}
enc.EncodeElement(unitTypes[e-1], start)
return nil
}
// NewUnitType returns returns an 'enum' value of type unitType given its
// string representation
func NewUnitType(s string) (unitType, error) {
var e unitType
err := e.FromString(s)
if err != nil {
return 0, err
}
return e, nil
}
type optBuyType uint
// OptBuyType* constants represent types of purchases for options
const (
OptBuyTypeBuyToOpen optBuyType = 1 + iota
OptBuyTypeBuyToClose
)
var optBuyTypes = [...]string{"BUYTOOPEN", "BUYTOCLOSE"}
func (e optBuyType) Valid() bool {
// This check is mostly out of paranoia, ensuring e != 0 should be
// sufficient
return e >= OptBuyTypeBuyToOpen && e <= OptBuyTypeBuyToClose
}
func (e optBuyType) String() string {
if e.Valid() {
return optBuyTypes[e-1]
}
return fmt.Sprintf("invalid optBuyType (%d)", e)
}
func (e *optBuyType) FromString(in string) error {
value := strings.TrimSpace(in)
for i, s := range optBuyTypes {
if s == value {
*e = optBuyType(i + 1)
return nil
}
}
*e = 0
return errors.New("Invalid OptBuyType: \"" + in + "\"")
}
func (e *optBuyType) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var value string
err := d.DecodeElement(&value, &start)
if err != nil {
return err
}
return e.FromString(value)
}
func (e optBuyType) MarshalXML(enc *xml.Encoder, start xml.StartElement) error {
if !e.Valid() {
return nil
}
enc.EncodeElement(optBuyTypes[e-1], start)
return nil
}
// NewOptBuyType returns returns an 'enum' value of type optBuyType given its
// string representation
func NewOptBuyType(s string) (optBuyType, error) {
var e optBuyType
err := e.FromString(s)
if err != nil {
return 0, err
}
return e, nil
}
type sellType uint
// SellType* constants represent types of sales
const (
SellTypeSell sellType = 1 + iota
SellTypeSellShort
)
var sellTypes = [...]string{"SELL", "SELLSHORT"}
func (e sellType) Valid() bool {
// This check is mostly out of paranoia, ensuring e != 0 should be
// sufficient
return e >= SellTypeSell && e <= SellTypeSellShort
}
func (e sellType) String() string {
if e.Valid() {
return sellTypes[e-1]
}
return fmt.Sprintf("invalid sellType (%d)", e)
}
func (e *sellType) FromString(in string) error {
value := strings.TrimSpace(in)
for i, s := range sellTypes {
if s == value {
*e = sellType(i + 1)
return nil
}
}
*e = 0
return errors.New("Invalid SellType: \"" + in + "\"")
}
func (e *sellType) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var value string
err := d.DecodeElement(&value, &start)
if err != nil {
return err
}
return e.FromString(value)
}
func (e sellType) MarshalXML(enc *xml.Encoder, start xml.StartElement) error {
if !e.Valid() {
return nil
}
enc.EncodeElement(sellTypes[e-1], start)
return nil
}
// NewSellType returns returns an 'enum' value of type sellType given its
// string representation
func NewSellType(s string) (sellType, error) {
var e sellType
err := e.FromString(s)
if err != nil {
return 0, err
}
return e, nil
}
type loanPmtFreq uint
// LoanPmtFreq* constants represent the frequency of loan payments
const (
LoanPmtFreqWeekly loanPmtFreq = 1 + iota
LoanPmtFreqBiweekly
LoanPmtFreqTwiceMonthly
LoanPmtFreqMonthly
LoanPmtFreqFourWeeks
LoanPmtFreqBiMonthly
LoanPmtFreqQuarterly
LoanPmtFreqSemiannually
LoanPmtFreqAnnually
LoanPmtFreqOther
)
var loanPmtFreqs = [...]string{"WEEKLY", "BIWEEKLY", "TWICEMONTHLY", "MONTHLY", "FOURWEEKS", "BIMONTHLY", "QUARTERLY", "SEMIANNUALLY", "ANNUALLY", "OTHER"}
func (e loanPmtFreq) Valid() bool {
// This check is mostly out of paranoia, ensuring e != 0 should be
// sufficient
return e >= LoanPmtFreqWeekly && e <= LoanPmtFreqOther
}
func (e loanPmtFreq) String() string {
if e.Valid() {
return loanPmtFreqs[e-1]
}
return fmt.Sprintf("invalid loanPmtFreq (%d)", e)
}
func (e *loanPmtFreq) FromString(in string) error {
value := strings.TrimSpace(in)
for i, s := range loanPmtFreqs {
if s == value {
*e = loanPmtFreq(i + 1)
return nil
}
}
*e = 0
return errors.New("Invalid LoanPmtFreq: \"" + in + "\"")
}
func (e *loanPmtFreq) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var value string
err := d.DecodeElement(&value, &start)
if err != nil {
return err
}
return e.FromString(value)
}
func (e loanPmtFreq) MarshalXML(enc *xml.Encoder, start xml.StartElement) error {
if !e.Valid() {
return nil
}
enc.EncodeElement(loanPmtFreqs[e-1], start)
return nil
}
// NewLoanPmtFreq returns returns an 'enum' value of type loanPmtFreq given its
// string representation
func NewLoanPmtFreq(s string) (loanPmtFreq, error) {
var e loanPmtFreq
err := e.FromString(s)
if err != nil {
return 0, err
}
return e, nil
}
type incomeType uint
// IncomeType* constants represent types of investment income
const (
IncomeTypeCGLong incomeType = 1 + iota
IncomeTypeCGShort
IncomeTypeDiv
IncomeTypeInterest
IncomeTypeMisc
)
var incomeTypes = [...]string{"CGLONG", "CGSHORT", "DIV", "INTEREST", "MISC"}
func (e incomeType) Valid() bool {
// This check is mostly out of paranoia, ensuring e != 0 should be
// sufficient
return e >= IncomeTypeCGLong && e <= IncomeTypeMisc
}
func (e incomeType) String() string {
if e.Valid() {
return incomeTypes[e-1]
}
return fmt.Sprintf("invalid incomeType (%d)", e)
}
func (e *incomeType) FromString(in string) error {
value := strings.TrimSpace(in)
for i, s := range incomeTypes {
if s == value {
*e = incomeType(i + 1)
return nil
}
}
*e = 0
return errors.New("Invalid IncomeType: \"" + in + "\"")
}
func (e *incomeType) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var value string
err := d.DecodeElement(&value, &start)
if err != nil {
return err
}
return e.FromString(value)
}
func (e incomeType) MarshalXML(enc *xml.Encoder, start xml.StartElement) error {
if !e.Valid() {
return nil
}
enc.EncodeElement(incomeTypes[e-1], start)
return nil
}
// NewIncomeType returns returns an 'enum' value of type incomeType given its
// string representation
func NewIncomeType(s string) (incomeType, error) {
var e incomeType
err := e.FromString(s)
if err != nil {
return 0, err
}
return e, nil
}
type sellReason uint
// SellReason* constants represent the reason the sell of a debt security was generated: CALL (the debt was called), SELL (the debt was sold), MATURITY (the debt reached maturity)
const (
SellReasonCall sellReason = 1 + iota
SellReasonSell
SellReasonMaturity
)
var sellReasons = [...]string{"CALL", "SELL", "MATURITY"}
func (e sellReason) Valid() bool {
// This check is mostly out of paranoia, ensuring e != 0 should be
// sufficient
return e >= SellReasonCall && e <= SellReasonMaturity
}
func (e sellReason) String() string {
if e.Valid() {
return sellReasons[e-1]
}
return fmt.Sprintf("invalid sellReason (%d)", e)
}
func (e *sellReason) FromString(in string) error {
value := strings.TrimSpace(in)
for i, s := range sellReasons {
if s == value {
*e = sellReason(i + 1)
return nil
}
}
*e = 0
return errors.New("Invalid SellReason: \"" + in + "\"")
}
func (e *sellReason) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var value string
err := d.DecodeElement(&value, &start)
if err != nil {
return err
}
return e.FromString(value)
}
func (e sellReason) MarshalXML(enc *xml.Encoder, start xml.StartElement) error {
if !e.Valid() {
return nil
}
enc.EncodeElement(sellReasons[e-1], start)
return nil
}
// NewSellReason returns returns an 'enum' value of type sellReason given its
// string representation
func NewSellReason(s string) (sellReason, error) {
var e sellReason
err := e.FromString(s)
if err != nil {
return 0, err
}
return e, nil
}
type optSellType uint
// OptSellType* constants represent types of sales for options
const (
OptSellTypeSellToClose optSellType = 1 + iota
OptSellTypeSellToOpen
)
var optSellTypes = [...]string{"SELLTOCLOSE", "SELLTOOPEN"}
func (e optSellType) Valid() bool {
// This check is mostly out of paranoia, ensuring e != 0 should be
// sufficient
return e >= OptSellTypeSellToClose && e <= OptSellTypeSellToOpen
}
func (e optSellType) String() string {
if e.Valid() {
return optSellTypes[e-1]
}
return fmt.Sprintf("invalid optSellType (%d)", e)
}
func (e *optSellType) FromString(in string) error {
value := strings.TrimSpace(in)
for i, s := range optSellTypes {
if s == value {
*e = optSellType(i + 1)
return nil
}
}
*e = 0
return errors.New("Invalid OptSellType: \"" + in + "\"")
}
func (e *optSellType) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var value string
err := d.DecodeElement(&value, &start)
if err != nil {
return err
}
return e.FromString(value)
}
func (e optSellType) MarshalXML(enc *xml.Encoder, start xml.StartElement) error {
if !e.Valid() {
return nil
}
enc.EncodeElement(optSellTypes[e-1], start)
return nil
}
// NewOptSellType returns returns an 'enum' value of type optSellType given its
// string representation
func NewOptSellType(s string) (optSellType, error) {
var e optSellType
err := e.FromString(s)
if err != nil {
return 0, err
}
return e, nil
}
type relType uint
// RelType* constants represent related option transaction types
const (
RelTypeSpread relType = 1 + iota
RelTypeStraddle
RelTypeNone
RelTypeOther
)
var relTypes = [...]string{"SPREAD", "STRADDLE", "NONE", "OTHER"}
func (e relType) Valid() bool {
// This check is mostly out of paranoia, ensuring e != 0 should be
// sufficient
return e >= RelTypeSpread && e <= RelTypeOther
}
func (e relType) String() string {
if e.Valid() {
return relTypes[e-1]
}
return fmt.Sprintf("invalid relType (%d)", e)
}
func (e *relType) FromString(in string) error {
value := strings.TrimSpace(in)
for i, s := range relTypes {
if s == value {
*e = relType(i + 1)
return nil
}
}
*e = 0
return errors.New("Invalid RelType: \"" + in + "\"")
}
func (e *relType) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var value string
err := d.DecodeElement(&value, &start)
if err != nil {
return err
}
return e.FromString(value)
}
func (e relType) MarshalXML(enc *xml.Encoder, start xml.StartElement) error {
if !e.Valid() {
return nil
}
enc.EncodeElement(relTypes[e-1], start)
return nil
}
// NewRelType returns returns an 'enum' value of type relType given its
// string representation
func NewRelType(s string) (relType, error) {
var e relType
err := e.FromString(s)
if err != nil {
return 0, err
}
return e, nil
}
type charType uint
// CharType* constants represent types of characters allowed in password
const (
CharTypeAlphaOnly charType = 1 + iota
CharTypeNumericOnly
CharTypeAlphaOrNumeric
CharTypeAlphaAndNumeric
)
var charTypes = [...]string{"ALPHAONLY", "NUMERICONLY", "ALPHAORNUMERIC", "ALPHAANDNUMERIC"}
func (e charType) Valid() bool {
// This check is mostly out of paranoia, ensuring e != 0 should be
// sufficient
return e >= CharTypeAlphaOnly && e <= CharTypeAlphaAndNumeric
}
func (e charType) String() string {
if e.Valid() {
return charTypes[e-1]
}
return fmt.Sprintf("invalid charType (%d)", e)
}
func (e *charType) FromString(in string) error {
value := strings.TrimSpace(in)
for i, s := range charTypes {
if s == value {
*e = charType(i + 1)
return nil
}
}
*e = 0
return errors.New("Invalid CharType: \"" + in + "\"")
}
func (e *charType) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var value string
err := d.DecodeElement(&value, &start)
if err != nil {
return err
}
return e.FromString(value)
}
func (e charType) MarshalXML(enc *xml.Encoder, start xml.StartElement) error {
if !e.Valid() {
return nil
}
enc.EncodeElement(charTypes[e-1], start)
return nil
}
// NewCharType returns returns an 'enum' value of type charType given its
// string representation
func NewCharType(s string) (charType, error) {
var e charType
err := e.FromString(s)
if err != nil {
return 0, err
}
return e, nil
}
type syncMode uint
// SyncMode* constants represent data synchronization mode supported (see OFX spec for more details)
const (
SyncModeFull syncMode = 1 + iota
SyncModeLite
)
var syncModes = [...]string{"FULL", "LITE"}
func (e syncMode) Valid() bool {
// This check is mostly out of paranoia, ensuring e != 0 should be
// sufficient
return e >= SyncModeFull && e <= SyncModeLite
}
func (e syncMode) String() string {
if e.Valid() {
return syncModes[e-1]
}
return fmt.Sprintf("invalid syncMode (%d)", e)
}
func (e *syncMode) FromString(in string) error {
value := strings.TrimSpace(in)
for i, s := range syncModes {
if s == value {
*e = syncMode(i + 1)
return nil
}
}
*e = 0
return errors.New("Invalid SyncMode: \"" + in + "\"")
}
func (e *syncMode) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var value string
err := d.DecodeElement(&value, &start)
if err != nil {
return err
}
return e.FromString(value)
}
func (e syncMode) MarshalXML(enc *xml.Encoder, start xml.StartElement) error {
if !e.Valid() {
return nil
}
enc.EncodeElement(syncModes[e-1], start)
return nil
}
// NewSyncMode returns returns an 'enum' value of type syncMode given its
// string representation
func NewSyncMode(s string) (syncMode, error) {
var e syncMode
err := e.FromString(s)
if err != nil {
return 0, err
}
return e, nil
}
type ofxSec uint
// OfxSec* constants represent the type of application-level security required for the message set
const (
OfxSecNone ofxSec = 1 + iota
OfxSecType1
)
var ofxSecs = [...]string{"NONE", "TYPE 1"}
func (e ofxSec) Valid() bool {
// This check is mostly out of paranoia, ensuring e != 0 should be
// sufficient
return e >= OfxSecNone && e <= OfxSecType1
}
func (e ofxSec) String() string {
if e.Valid() {
return ofxSecs[e-1]
}
return fmt.Sprintf("invalid ofxSec (%d)", e)
}
func (e *ofxSec) FromString(in string) error {
value := strings.TrimSpace(in)
for i, s := range ofxSecs {
if s == value {
*e = ofxSec(i + 1)
return nil
}
}
*e = 0
return errors.New("Invalid OfxSec: \"" + in + "\"")
}
func (e *ofxSec) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var value string
err := d.DecodeElement(&value, &start)
if err != nil {
return err
}
return e.FromString(value)
}
func (e ofxSec) MarshalXML(enc *xml.Encoder, start xml.StartElement) error {
if !e.Valid() {
return nil
}
enc.EncodeElement(ofxSecs[e-1], start)
return nil
}
// NewOfxSec returns returns an 'enum' value of type ofxSec given its
// string representation
func NewOfxSec(s string) (ofxSec, error) {
var e ofxSec
err := e.FromString(s)
if err != nil {
return 0, err
}
return e, nil
}
type debtType uint
// DebtType* constants represent debt type
const (
DebtTypeCoupon debtType = 1 + iota
DebtTypeZero
)
var debtTypes = [...]string{"COUPON", "ZERO"}
func (e debtType) Valid() bool {
// This check is mostly out of paranoia, ensuring e != 0 should be
// sufficient
return e >= DebtTypeCoupon && e <= DebtTypeZero
}
func (e debtType) String() string {
if e.Valid() {
return debtTypes[e-1]
}
return fmt.Sprintf("invalid debtType (%d)", e)
}
func (e *debtType) FromString(in string) error {
value := strings.TrimSpace(in)
for i, s := range debtTypes {
if s == value {
*e = debtType(i + 1)
return nil
}
}
*e = 0
return errors.New("Invalid DebtType: \"" + in + "\"")
}
func (e *debtType) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var value string
err := d.DecodeElement(&value, &start)
if err != nil {
return err
}
return e.FromString(value)
}
func (e debtType) MarshalXML(enc *xml.Encoder, start xml.StartElement) error {
if !e.Valid() {
return nil
}
enc.EncodeElement(debtTypes[e-1], start)
return nil
}
// NewDebtType returns returns an 'enum' value of type debtType given its
// string representation
func NewDebtType(s string) (debtType, error) {
var e debtType
err := e.FromString(s)
if err != nil {
return 0, err
}
return e, nil
}
type debtClass uint
// DebtClass* constants represent the class of debt
const (
DebtClassTreasury debtClass = 1 + iota
DebtClassMunicipal
DebtClassCorporate
DebtClassOther
)
var debtClasss = [...]string{"TREASURY", "MUNICIPAL", "CORPORATE", "OTHER"}
func (e debtClass) Valid() bool {
// This check is mostly out of paranoia, ensuring e != 0 should be
// sufficient
return e >= DebtClassTreasury && e <= DebtClassOther
}
func (e debtClass) String() string {
if e.Valid() {
return debtClasss[e-1]
}
return fmt.Sprintf("invalid debtClass (%d)", e)
}
func (e *debtClass) FromString(in string) error {
value := strings.TrimSpace(in)
for i, s := range debtClasss {
if s == value {
*e = debtClass(i + 1)
return nil
}
}
*e = 0
return errors.New("Invalid DebtClass: \"" + in + "\"")
}
func (e *debtClass) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var value string
err := d.DecodeElement(&value, &start)
if err != nil {
return err
}
return e.FromString(value)
}
func (e debtClass) MarshalXML(enc *xml.Encoder, start xml.StartElement) error {
if !e.Valid() {
return nil
}
enc.EncodeElement(debtClasss[e-1], start)
return nil
}
// NewDebtClass returns returns an 'enum' value of type debtClass given its
// string representation
func NewDebtClass(s string) (debtClass, error) {
var e debtClass
err := e.FromString(s)
if err != nil {
return 0, err
}
return e, nil
}
type couponFreq uint
// CouponFreq* constants represent when debt coupons mature
const (
CouponFreqMonthly couponFreq = 1 + iota
CouponFreqQuarterly
CouponFreqSemiannual
CouponFreqAnnual
CouponFreqOther
)
var couponFreqs = [...]string{"MONTHLY", "QUARTERLY", "SEMIANNUAL", "ANNUAL", "OTHER"}
func (e couponFreq) Valid() bool {
// This check is mostly out of paranoia, ensuring e != 0 should be
// sufficient
return e >= CouponFreqMonthly && e <= CouponFreqOther
}
func (e couponFreq) String() string {
if e.Valid() {
return couponFreqs[e-1]
}
return fmt.Sprintf("invalid couponFreq (%d)", e)
}
func (e *couponFreq) FromString(in string) error {
value := strings.TrimSpace(in)
for i, s := range couponFreqs {
if s == value {
*e = couponFreq(i + 1)
return nil
}
}
*e = 0
return errors.New("Invalid CouponFreq: \"" + in + "\"")
}
func (e *couponFreq) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var value string
err := d.DecodeElement(&value, &start)
if err != nil {
return err
}
return e.FromString(value)
}
func (e couponFreq) MarshalXML(enc *xml.Encoder, start xml.StartElement) error {
if !e.Valid() {
return nil
}
enc.EncodeElement(couponFreqs[e-1], start)
return nil
}
// NewCouponFreq returns returns an 'enum' value of type couponFreq given its
// string representation
func NewCouponFreq(s string) (couponFreq, error) {
var e couponFreq
err := e.FromString(s)
if err != nil {
return 0, err
}
return e, nil
}
type callType uint
// CallType* constants represent type of next call (for a debt)
const (
CallTypeCall callType = 1 + iota
CallTypePut
CallTypePrefund
CallTypeMaturity
)
var callTypes = [...]string{"CALL", "PUT", "PREFUND", "MATURITY"}
func (e callType) Valid() bool {
// This check is mostly out of paranoia, ensuring e != 0 should be
// sufficient
return e >= CallTypeCall && e <= CallTypeMaturity
}
func (e callType) String() string {
if e.Valid() {
return callTypes[e-1]
}
return fmt.Sprintf("invalid callType (%d)", e)
}
func (e *callType) FromString(in string) error {
value := strings.TrimSpace(in)
for i, s := range callTypes {
if s == value {
*e = callType(i + 1)
return nil
}
}
*e = 0
return errors.New("Invalid CallType: \"" + in + "\"")
}
func (e *callType) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var value string
err := d.DecodeElement(&value, &start)
if err != nil {
return err
}
return e.FromString(value)
}
func (e callType) MarshalXML(enc *xml.Encoder, start xml.StartElement) error {
if !e.Valid() {
return nil
}
enc.EncodeElement(callTypes[e-1], start)
return nil
}
// NewCallType returns returns an 'enum' value of type callType given its
// string representation
func NewCallType(s string) (callType, error) {
var e callType
err := e.FromString(s)
if err != nil {
return 0, err
}
return e, nil
}
type assetClass uint
// AssetClass* constants represent type of asset classes
const (
AssetClassDomesticBond assetClass = 1 + iota
AssetClassIntlBond
AssetClassLargeStock
AssetClassSmallStock
AssetClassIntlStock
AssetClassMoneyMrkt
AssetClassOther
)
var assetClasss = [...]string{"DOMESTICBOND", "INTLBOND", "LARGESTOCK", "SMALLSTOCK", "INTLSTOCK", "MONEYMRKT", "OTHER"}
func (e assetClass) Valid() bool {
// This check is mostly out of paranoia, ensuring e != 0 should be
// sufficient
return e >= AssetClassDomesticBond && e <= AssetClassOther
}
func (e assetClass) String() string {
if e.Valid() {
return assetClasss[e-1]
}
return fmt.Sprintf("invalid assetClass (%d)", e)
}
func (e *assetClass) FromString(in string) error {
value := strings.TrimSpace(in)
for i, s := range assetClasss {
if s == value {
*e = assetClass(i + 1)
return nil
}
}
*e = 0
return errors.New("Invalid AssetClass: \"" + in + "\"")
}
func (e *assetClass) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var value string
err := d.DecodeElement(&value, &start)
if err != nil {
return err
}
return e.FromString(value)
}
func (e assetClass) MarshalXML(enc *xml.Encoder, start xml.StartElement) error {
if !e.Valid() {
return nil
}
enc.EncodeElement(assetClasss[e-1], start)
return nil
}
// NewAssetClass returns returns an 'enum' value of type assetClass given its
// string representation
func NewAssetClass(s string) (assetClass, error) {
var e assetClass
err := e.FromString(s)
if err != nil {
return 0, err
}
return e, nil
}
type mfType uint
// MfType* constants represent types of mutual funds
const (
MfTypeOpenEnd mfType = 1 + iota
MfTypeCloseEnd
MfTypeOther
)
var mfTypes = [...]string{"OPENEND", "CLOSEEND", "OTHER"}
func (e mfType) Valid() bool {
// This check is mostly out of paranoia, ensuring e != 0 should be
// sufficient
return e >= MfTypeOpenEnd && e <= MfTypeOther
}
func (e mfType) String() string {
if e.Valid() {
return mfTypes[e-1]
}
return fmt.Sprintf("invalid mfType (%d)", e)
}
func (e *mfType) FromString(in string) error {
value := strings.TrimSpace(in)
for i, s := range mfTypes {
if s == value {
*e = mfType(i + 1)
return nil
}
}
*e = 0
return errors.New("Invalid MfType: \"" + in + "\"")
}
func (e *mfType) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var value string
err := d.DecodeElement(&value, &start)
if err != nil {
return err
}
return e.FromString(value)
}
func (e mfType) MarshalXML(enc *xml.Encoder, start xml.StartElement) error {
if !e.Valid() {
return nil
}
enc.EncodeElement(mfTypes[e-1], start)
return nil
}
// NewMfType returns returns an 'enum' value of type mfType given its
// string representation
func NewMfType(s string) (mfType, error) {
var e mfType
err := e.FromString(s)
if err != nil {
return 0, err
}
return e, nil
}
type optType uint
// OptType* constants represent whether the option is a PUT or a CALL
const (
OptTypePut optType = 1 + iota
OptTypeCall
)
var optTypes = [...]string{"PUT", "CALL"}
func (e optType) Valid() bool {
// This check is mostly out of paranoia, ensuring e != 0 should be
// sufficient
return e >= OptTypePut && e <= OptTypeCall
}
func (e optType) String() string {
if e.Valid() {
return optTypes[e-1]
}
return fmt.Sprintf("invalid optType (%d)", e)
}
func (e *optType) FromString(in string) error {
value := strings.TrimSpace(in)
for i, s := range optTypes {
if s == value {
*e = optType(i + 1)
return nil
}
}
*e = 0
return errors.New("Invalid OptType: \"" + in + "\"")
}
func (e *optType) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var value string
err := d.DecodeElement(&value, &start)
if err != nil {
return err
}
return e.FromString(value)
}
func (e optType) MarshalXML(enc *xml.Encoder, start xml.StartElement) error {
if !e.Valid() {
return nil
}
enc.EncodeElement(optTypes[e-1], start)
return nil
}
// NewOptType returns returns an 'enum' value of type optType given its
// string representation
func NewOptType(s string) (optType, error) {
var e optType
err := e.FromString(s)
if err != nil {
return 0, err
}
return e, nil
}
type stockType uint
// StockType* constants represent types of stock
const (
StockTypeCommon stockType = 1 + iota
StockTypePreferred
StockTypeConvertible
StockTypeOther
)
var stockTypes = [...]string{"COMMON", "PREFERRED", "CONVERTIBLE", "OTHER"}
func (e stockType) Valid() bool {
// This check is mostly out of paranoia, ensuring e != 0 should be
// sufficient
return e >= StockTypeCommon && e <= StockTypeOther
}
func (e stockType) String() string {
if e.Valid() {
return stockTypes[e-1]
}
return fmt.Sprintf("invalid stockType (%d)", e)
}
func (e *stockType) FromString(in string) error {
value := strings.TrimSpace(in)
for i, s := range stockTypes {
if s == value {
*e = stockType(i + 1)
return nil
}
}
*e = 0
return errors.New("Invalid StockType: \"" + in + "\"")
}
func (e *stockType) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var value string
err := d.DecodeElement(&value, &start)
if err != nil {
return err
}
return e.FromString(value)
}
func (e stockType) MarshalXML(enc *xml.Encoder, start xml.StartElement) error {
if !e.Valid() {
return nil
}
enc.EncodeElement(stockTypes[e-1], start)
return nil
}
// NewStockType returns returns an 'enum' value of type stockType given its
// string representation
func NewStockType(s string) (stockType, error) {
var e stockType
err := e.FromString(s)
if err != nil {
return 0, err
}
return e, nil
}
type holderType uint
// HolderType* constants represent how the account is held
const (
HolderTypeIndividual holderType = 1 + iota
HolderTypeJoint
HolderTypeCustodial
HolderTypeTrust
HolderTypeOther
)
var holderTypes = [...]string{"INDIVIDUAL", "JOINT", "CUSTODIAL", "TRUST", "OTHER"}
func (e holderType) Valid() bool {
// This check is mostly out of paranoia, ensuring e != 0 should be
// sufficient
return e >= HolderTypeIndividual && e <= HolderTypeOther
}
func (e holderType) String() string {
if e.Valid() {
return holderTypes[e-1]
}
return fmt.Sprintf("invalid holderType (%d)", e)
}
func (e *holderType) FromString(in string) error {
value := strings.TrimSpace(in)
for i, s := range holderTypes {
if s == value {
*e = holderType(i + 1)
return nil
}
}
*e = 0
return errors.New("Invalid HolderType: \"" + in + "\"")
}
func (e *holderType) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var value string
err := d.DecodeElement(&value, &start)
if err != nil {
return err
}
return e.FromString(value)
}
func (e holderType) MarshalXML(enc *xml.Encoder, start xml.StartElement) error {
if !e.Valid() {
return nil
}
enc.EncodeElement(holderTypes[e-1], start)
return nil
}
// NewHolderType returns returns an 'enum' value of type holderType given its
// string representation
func NewHolderType(s string) (holderType, error) {
var e holderType
err := e.FromString(s)
if err != nil {
return 0, err
}
return e, nil
}
type acctClassification uint
// AcctClassification* constants represent the type of an account
const (
AcctClassificationPersonal acctClassification = 1 + iota
AcctClassificationBusiness
AcctClassificationCorporate
AcctClassificationOther
)
var acctClassifications = [...]string{"PERSONAL", "BUSINESS", "CORPORATE", "OTHER"}
func (e acctClassification) Valid() bool {
// This check is mostly out of paranoia, ensuring e != 0 should be
// sufficient
return e >= AcctClassificationPersonal && e <= AcctClassificationOther
}
func (e acctClassification) String() string {
if e.Valid() {
return acctClassifications[e-1]
}
return fmt.Sprintf("invalid acctClassification (%d)", e)
}
func (e *acctClassification) FromString(in string) error {
value := strings.TrimSpace(in)
for i, s := range acctClassifications {
if s == value {
*e = acctClassification(i + 1)
return nil
}
}
*e = 0
return errors.New("Invalid AcctClassification: \"" + in + "\"")
}
func (e *acctClassification) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var value string
err := d.DecodeElement(&value, &start)
if err != nil {
return err
}
return e.FromString(value)
}
func (e acctClassification) MarshalXML(enc *xml.Encoder, start xml.StartElement) error {
if !e.Valid() {
return nil
}
enc.EncodeElement(acctClassifications[e-1], start)
return nil
}
// NewAcctClassification returns returns an 'enum' value of type acctClassification given its
// string representation
func NewAcctClassification(s string) (acctClassification, error) {
var e acctClassification
err := e.FromString(s)
if err != nil {
return 0, err
}
return e, nil
}
type svcStatus uint
// SvcStatus* constants represent the status of the account: AVAIL = Available, but not yet requested, PEND = Requested, but not yet available, ACTIVE = In use
const (
SvcStatusAvail svcStatus = 1 + iota
SvcStatusPend
SvcStatusActive
)
var svcStatuss = [...]string{"AVAIL", "PEND", "ACTIVE"}
func (e svcStatus) Valid() bool {
// This check is mostly out of paranoia, ensuring e != 0 should be
// sufficient
return e >= SvcStatusAvail && e <= SvcStatusActive
}
func (e svcStatus) String() string {
if e.Valid() {
return svcStatuss[e-1]
}
return fmt.Sprintf("invalid svcStatus (%d)", e)
}
func (e *svcStatus) FromString(in string) error {
value := strings.TrimSpace(in)
for i, s := range svcStatuss {
if s == value {
*e = svcStatus(i + 1)
return nil
}
}
*e = 0
return errors.New("Invalid SvcStatus: \"" + in + "\"")
}
func (e *svcStatus) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var value string
err := d.DecodeElement(&value, &start)
if err != nil {
return err
}
return e.FromString(value)
}
func (e svcStatus) MarshalXML(enc *xml.Encoder, start xml.StartElement) error {
if !e.Valid() {
return nil
}
enc.EncodeElement(svcStatuss[e-1], start)
return nil
}
// NewSvcStatus returns returns an 'enum' value of type svcStatus given its
// string representation
func NewSvcStatus(s string) (svcStatus, error) {
var e svcStatus
err := e.FromString(s)
if err != nil {
return 0, err
}
return e, nil
}
type usProductType uint
// UsProductType* constants represent type of investment account (in the US)
const (
UsProductType401K usProductType = 1 + iota
UsProductType403B
UsProductTypeIRA
UsProductTypeKEOGH
UsProductTypeOther
UsProductTypeSARSEP
UsProductTypeSimple
UsProductTypeNormal
UsProductTypeTDA
UsProductTypeTrust
UsProductTypeUGMA
)
var usProductTypes = [...]string{"401K", "403B", "IRA", "KEOGH", "OTHER", "SARSEP", "SIMPLE", "NORMAL", "TDA", "TRUST", "UGMA"}
func (e usProductType) Valid() bool {
// This check is mostly out of paranoia, ensuring e != 0 should be
// sufficient
return e >= UsProductType401K && e <= UsProductTypeUGMA
}
func (e usProductType) String() string {
if e.Valid() {
return usProductTypes[e-1]
}
return fmt.Sprintf("invalid usProductType (%d)", e)
}
func (e *usProductType) FromString(in string) error {
value := strings.TrimSpace(in)
for i, s := range usProductTypes {
if s == value {
*e = usProductType(i + 1)
return nil
}
}
*e = 0
return errors.New("Invalid UsProductType: \"" + in + "\"")
}
func (e *usProductType) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var value string
err := d.DecodeElement(&value, &start)
if err != nil {
return err
}
return e.FromString(value)
}
func (e usProductType) MarshalXML(enc *xml.Encoder, start xml.StartElement) error {
if !e.Valid() {
return nil
}
enc.EncodeElement(usProductTypes[e-1], start)
return nil
}
// NewUsProductType returns returns an 'enum' value of type usProductType given its
// string representation
func NewUsProductType(s string) (usProductType, error) {
var e usProductType
err := e.FromString(s)
if err != nil {
return 0, err
}
return e, nil
}
================================================
FILE: constants_test.go
================================================
package ofxgo
/*
* Do not edit this file by hand. It is auto-generated by calling `go generate`.
* To make changes, edit generate_constants.py, re-run `go generate`, and check
* in the result.
*/
import (
"strings"
"testing"
"github.com/aclindsa/xml"
)
func TestOfxVersion(t *testing.T) {
e, err := NewOfxVersion("102")
if err != nil {
t.Fatalf("Unexpected error creating new OfxVersion from string \"102\"\n")
}
if !e.Valid() {
t.Fatalf("OfxVersion unexpectedly invalid\n")
}
err = e.FromString("220")
if err != nil {
t.Fatalf("Unexpected error on OfxVersion.FromString(\"220\")\n")
}
if e.String() != "220" {
t.Fatalf("OfxVersion.String() expected to be \"220\"\n")
}
marshalHelper(t, "220", &e)
overwritten, err := NewOfxVersion("THISWILLNEVERBEAVALIDENUMSTRING")
if err == nil {
t.Fatalf("Expected error creating new OfxVersion from string \"THISWILLNEVERBEAVALIDENUMSTRING\"\n")
}
if overwritten.Valid() {
t.Fatalf("OfxVersion created with string \"THISWILLNEVERBEAVALIDENUMSTRING\" should not be valid\n")
}
if !strings.Contains(strings.ToLower(overwritten.String()), "invalid") {
t.Fatalf("OfxVersion created with string \"THISWILLNEVERBEAVALIDENUMSTRING\" should not return valid string from String()\n")
}
b, err := xml.Marshal(&overwritten)
if err != nil {
t.Fatalf("Unexpected error on xml.Marshal(OfxVersion): %s\n", err)
}
if string(b) != "" {
t.Fatalf("Expected empty string, got '%s'\n", string(b))
}
unmarshalHelper(t, "220", &e, &overwritten)
err = xml.Unmarshal([]byte("<GARBAGE><!LALDK>"), &overwritten)
if err == nil {
t.Fatalf("Expected error unmarshalling garbage value\n")
}
type SC struct {
E ofxVersion
}
sc := SC{E: e}
b, err = xml.Marshal(sc)
if err != nil {
t.Fatalf("Unexpected error on xml.Marshal(struct OfxVersion): %s\n", err)
}
if string(b) != "<SC><E>220</E></SC>" {
t.Fatalf("Expected '%s', got '%s'\n", "<SC><E>220</E></SC>", string(b))
}
}
func TestAcctType(t *testing.T) {
e, err := NewAcctType("CHECKING")
if err != nil {
t.Fatalf("Unexpected error creating new AcctType from string \"CHECKING\"\n")
}
if !e.Valid() {
t.Fatalf("AcctType unexpectedly invalid\n")
}
err = e.FromString("CD")
if err != nil {
t.Fatalf("Unexpected error on AcctType.FromString(\"CD\")\n")
}
if e.String() != "CD" {
t.Fatalf("AcctType.String() expected to be \"CD\"\n")
}
marshalHelper(t, "CD", &e)
overwritten, err := NewAcctType("THISWILLNEVERBEAVALIDENUMSTRING")
if err == nil {
t.Fatalf("Expected error creating new AcctType from string \"THISWILLNEVERBEAVALIDENUMSTRING\"\n")
}
if overwritten.Valid() {
t.Fatalf("AcctType created with string \"THISWILLNEVERBEAVALIDENUMSTRING\" should not be valid\n")
}
if !strings.Contains(strings.ToLower(overwritten.String()), "invalid") {
t.Fatalf("AcctType created with string \"THISWILLNEVERBEAVALIDENUMSTRING\" should not return valid string from String()\n")
}
b, err := xml.Marshal(&overwritten)
if err != nil {
t.Fatalf("Unexpected error on xml.Marshal(AcctType): %s\n", err)
}
if string(b) != "" {
t.Fatalf("Expected empty string, got '%s'\n", string(b))
}
unmarshalHelper(t, "CD", &e, &overwritten)
err = xml.Unmarshal([]byte("<GARBAGE><!LALDK>"), &overwritten)
if err == nil {
t.Fatalf("Expected error unmarshalling garbage value\n")
}
type SC struct {
E acctType
}
sc := SC{E: e}
b, err = xml.Marshal(sc)
if err != nil {
t.Fatalf("Unexpected error on xml.Marshal(struct AcctType): %s\n", err)
}
if string(b) != "<SC><E>CD</E></SC>" {
t.Fatalf("Expected '%s', got '%s'\n", "<SC><E>CD</E></SC>", string(b))
}
}
func TestTrnType(t *testing.T) {
e, err := NewTrnType("CREDIT")
if err != nil {
t.Fatalf("Unexpected error creating new TrnType from string \"CREDIT\"\n")
}
if !e.Valid() {
t.Fatalf("TrnType unexpectedly invalid\n")
}
err = e.FromString("OTHER")
if err != nil {
t.Fatalf("Unexpected error on TrnType.FromString(\"OTHER\")\n")
}
if e.String() != "OTHER" {
t.Fatalf("TrnType.String() expected to be \"OTHER\"\n")
}
marshalHelper(t, "OTHER", &e)
overwritten, err := NewTrnType("THISWILLNEVERBEAVALIDENUMSTRING")
if err == nil {
t.Fatalf("Expected error creating new TrnType from string \"THISWILLNEVERBEAVALIDENUMSTRING\"\n")
}
if overwritten.Valid() {
t.Fatalf("TrnType created with string \"THISWILLNEVERBEAVALIDENUMSTRING\" should not be valid\n")
}
if !strings.Contains(strings.ToLower(overwritten.String()), "invalid") {
t.Fatalf("TrnType created with string \"THISWILLNEVERBEAVALIDENUMSTRING\" should not return valid string from String()\n")
}
b, err := xml.Marshal(&overwritten)
if err != nil {
t.Fatalf("Unexpected error on xml.Marshal(TrnType): %s\n", err)
}
if string(b) != "" {
t.Fatalf("Expected empty string, got '%s'\n", string(b))
}
unmarshalHelper(t, "OTHER", &e, &overwritten)
err = xml.Unmarshal([]byte("<GARBAGE><!LALDK>"), &overwritten)
if err == nil {
t.Fatalf("Expected error unmarshalling garbage value\n")
}
type SC struct {
E trnType
}
sc := SC{E: e}
b, err = xml.Marshal(sc)
if err != nil {
t.Fatalf("Unexpected error on xml.Marshal(struct TrnType): %s\n", err)
}
if string(b) != "<SC><E>OTHER</E></SC>" {
t.Fatalf("Expected '%s', got '%s'\n", "<SC><E>OTHER</E></SC>", string(b))
}
}
func TestImageType(t *testing.T) {
e, err := NewImageType("STATEMENT")
if err != nil {
t.Fatalf("Unexpected error creating new ImageType from string \"STATEMENT\"\n")
}
if !e.Valid() {
t.Fatalf("ImageType unexpectedly invalid\n")
}
err = e.FromString("TAX")
if err != nil {
t.Fatalf("Unexpected error on ImageType.FromString(\"TAX\")\n")
}
if e.String() != "TAX" {
t.Fatalf("ImageType.String() expected to be \"TAX\"\n")
}
marshalHelper(t, "TAX", &e)
overwritten, err := NewImageType("THISWILLNEVERBEAVALIDENUMSTRING")
if err == nil {
t.Fatalf("Expected error creating new ImageType from string \"THISWILLNEVERBEAVALIDENUMSTRING\"\n")
}
if overwritten.Valid() {
t.Fatalf("ImageType created with string \"THISWILLNEVERBEAVALIDENUMSTRING\" should not be valid\n")
}
if !strings.Contains(strings.ToLower(overwritten.String()), "invalid") {
t.Fatalf("ImageType created with string \"THISWILLNEVERBEAVALIDENUMSTRING\" should not return valid string from String()\n")
}
b, err := xml.Marshal(&overwritten)
if err != nil {
t.Fatalf("Unexpected error on xml.Marshal(ImageType): %s\n", err)
}
if string(b) != "" {
t.Fatalf("Expected empty string, got '%s'\n", string(b))
}
unmarshalHelper(t, "TAX", &e, &overwritten)
err = xml.Unmarshal([]byte("<GARBAGE><!LALDK>"), &overwritten)
if err == nil {
t.Fatalf("Expected error unmarshalling garbage value\n")
}
type SC struct {
E imageType
}
sc := SC{E: e}
b, err = xml.Marshal(sc)
if err != nil {
t.Fatalf("Unexpected error on xml.Marshal(struct ImageType): %s\n", err)
}
if string(b) != "<SC><E>TAX</E></SC>" {
t.Fatalf("Expected '%s', got '%s'\n", "<SC><E>TAX</E></SC>", string(b))
}
}
func TestImageRefType(t *testing.T) {
e, err := NewImageRefType("OPAQUE")
if err != nil {
t.Fatalf("Unexpected error creating new ImageRefType from string \"OPAQUE\"\n")
}
if !e.Valid() {
t.Fatalf("ImageRefType unexpectedly invalid\n")
}
err = e.FromString("FORMURL")
if err != nil {
t.Fatalf("Unexpected error on ImageRefType.FromString(\"FORMURL\")\n")
}
if e.String() != "FORMURL" {
t.Fatalf("ImageRefType.String() expected to be \"FORMURL\"\n")
}
marshalHelper(t, "FORMURL", &e)
overwritten, err := NewImageRefType("THISWILLNEVERBEAVALIDENUMSTRING")
if err == nil {
t.Fatalf("Expected error creating new ImageRefType from string \"THISWILLNEVERBEAVALIDENUMSTRING\"\n")
}
if overwritten.Valid() {
t.Fatalf("ImageRefType created with string \"THISWILLNEVERBEAVALIDENUMSTRING\" should not be valid\n")
}
if !strings.Contains(strings.ToLower(overwritten.String()), "invalid") {
t.Fatalf("ImageRefType created with string \"THISWILLNEVERBEAVALIDENUMSTRING\" should not return valid string from String()\n")
}
b, err := xml.Marshal(&overwritten)
if err != nil {
t.Fatalf("Unexpected error on xml.Marshal(ImageRefType): %s\n", err)
}
if string(b) != "" {
t.Fatalf("Expected empty string, got '%s'\n", string(b))
}
unmarshalHelper(t, "FORMURL", &e, &overwritten)
err = xml.Unmarshal([]byte("<GARBAGE><!LALDK>"), &overwritten)
if err == nil {
t.Fatalf("Expected error unmarshalling garbage value\n")
}
type SC struct {
E imageRefType
}
sc := SC{E: e}
b, err = xml.Marshal(sc)
if err != nil {
t.Fatalf("Unexpected error on xml.Marshal(struct ImageRefType): %s\n", err)
}
if string(b) != "<SC><E>FORMURL</E></SC>" {
t.Fatalf("Expected '%s', got '%s'\n", "<SC><E>FORMURL</E></SC>", string(b))
}
}
func TestCheckSup(t *testing.T) {
e, err := NewCheckSup("FRONTONLY")
if err != nil {
t.Fatalf("Unexpected error creating new CheckSup from string \"FRONTONLY\"\n")
}
if !e.Valid() {
t.Fatalf("CheckSup unexpectedly invalid\n")
}
err = e.FromString("FRONTANDBACK")
if err != nil {
t.Fatalf("Unexpected error on CheckSup.FromString(\"FRONTANDBACK\")\n")
}
if e.String() != "FRONTANDBACK" {
t.Fatalf("CheckSup.String() expected to be \"FRONTANDBACK\"\n")
}
marshalHelper(t, "FRONTANDBACK", &e)
overwritten, err := NewCheckSup("THISWILLNEVERBEAVALIDENUMSTRING")
if err == nil {
t.Fatalf("Expected error creating new CheckSup from string \"THISWILLNEVERBEAVALIDENUMSTRING\"\n")
}
if overwritten.Valid() {
t.Fatalf("CheckSup created with string \"THISWILLNEVERBEAVALIDENUMSTRING\" should not be valid\n")
}
if !strings.Contains(strings.ToLower(overwritten.String()), "invalid") {
t.Fatalf("CheckSup created with string \"THISWILLNEVERBEAVALIDENUMSTRING\" should not return valid string from String()\n")
}
b, err := xml.Marshal(&overwritten)
if err != nil {
t.Fatalf("Unexpected error on xml.Marshal(CheckSup): %s\n", err)
}
if string(b) != "" {
t.Fatalf("Expected empty string, got '%s'\n", string(b))
}
unmarshalHelper(t, "FRONTANDBACK", &e, &overwritten)
err = xml.Unmarshal([]byte("<GARBAGE><!LALDK>"), &overwritten)
if err == nil {
t.Fatalf("Expected error unmarshalling garbage value\n")
}
type SC struct {
E checkSup
}
sc := SC{E: e}
b, err = xml.Marshal(sc)
if err != nil {
t.Fatalf("Unexpected error on xml.Marshal(struct CheckSup): %s\n", err)
}
if string(b) != "<SC><E>FRONTANDBACK</E></SC>" {
t.Fatalf("Expected '%s', got '%s'\n", "<SC><E>FRONTANDBACK</E></SC>", string(b))
}
}
func TestCorrectAction(t *testing.T) {
e, err := NewCorrectAction("DELETE")
if err != nil {
t.Fatalf("Unexpected error creating new CorrectAction from string \"DELETE\"\n")
}
if !e.Valid() {
t.Fatalf("CorrectAction unexpectedly invalid\n")
}
err = e.FromString("REPLACE")
if err != nil {
t.Fatalf("Unexpected error on CorrectAction.FromString(\"REPLACE\")\n")
}
if e.String() != "REPLACE" {
t.Fatalf("CorrectAction.String() expected to be \"REPLACE\"\n")
}
marshalHelper(t, "REPLACE", &e)
overwritten, err := NewCorrectAction("THISWILLNEVERBEAVALIDENUMSTRING")
if err == nil {
t.Fatalf("Expected error creating new CorrectAction from string \"THISWILLNEVERBEAVALIDENUMSTRING\"\n")
}
if overwritten.Valid() {
t.Fatalf("CorrectAction created with string \"THISWILLNEVERBEAVALIDENUMSTRING\" should not be valid\n")
}
if !strings.Contains(strings.ToLower(overwritten.String()), "invalid") {
t.Fatalf("CorrectAction created with string \"THISWILLNEVERBEAVALIDENUMSTRING\" should not return valid string from String()\n")
}
b, err := xml.Marshal(&overwritten)
if err != nil {
t.Fatalf("Unexpected error on xml.Marshal(CorrectAction): %s\n", err)
}
if string(b) != "" {
t.Fatalf("Expected empty string, got '%s'\n", string(b))
}
unmarshalHelper(t, "REPLACE", &e, &overwritten)
err = xml.Unmarshal([]byte("<GARBAGE><!LALDK>"), &overwritten)
if err == nil {
t.Fatalf("Expected error unmarshalling garbage value\n")
}
type SC struct {
E correctAction
}
sc := SC{E: e}
b, err = xml.Marshal(sc)
if err != nil {
t.Fatalf("Unexpected error on xml.Marshal(struct CorrectAction): %s\n", err)
}
if string(b) != "<SC><E>REPLACE</E></SC>" {
t.Fatalf("Expected '%s', got '%s'\n", "<SC><E>REPLACE</E></SC>", string(b))
}
}
func TestBalType(t *testing.T) {
e, err := NewBalType("DOLLAR")
if err != nil {
t.Fatalf("Unexpected error creating new BalType from string \"DOLLAR\"\n")
}
if !e.Valid() {
t.Fatalf("BalType unexpectedly invalid\n")
}
err = e.FromString("NUMBER")
if err != nil {
t.Fatalf("Unexpected error on BalType.FromString(\"NUMBER\")\n")
}
if e.String() != "NUMBER" {
t.Fatalf("BalType.String() expected to be \"NUMBER\"\n")
}
marshalHelper(t, "NUMBER", &e)
overwritten, err := NewBalType("THISWILLNEVERBEAVALIDENUMSTRING")
if err == nil {
t.Fatalf("Expected error creating new BalType from string \"THISWILLNEVERBEAVALIDENUMSTRING\"\n")
}
if overwritten.Valid() {
t.Fatalf("BalType created with string \"THISWILLNEVERBEAVALIDENUMSTRING\" should not be valid\n")
}
if !strings.Contains(strings.ToLower(overwritten.String()), "invalid") {
t.Fatalf("BalType created with string \"THISWILLNEVERBEAVALIDENUMSTRING\" should not return valid string from String()\n")
}
b, err := xml.Marshal(&overwritten)
if err != nil {
t.Fatalf("Unexpected error on xml.Marshal(BalType): %s\n", err)
}
if string(b) != "" {
t.Fatalf("Expected empty string, got '%s'\n", string(b))
}
unmarshalHelper(t, "NUMBER", &e, &overwritten)
err = xml.Unmarshal([]byte("<GARBAGE><!LALDK>"), &overwritten)
if err == nil {
t.Fatalf("Expected error unmarshalling garbage value\n")
}
type SC struct {
E balType
}
sc := SC{E: e}
b, err = xml.Marshal(sc)
if err != nil {
t.Fatalf("Unexpected error on xml.Marshal(struct BalType): %s\n", err)
}
if string(b) != "<SC><E>NUMBER</E></SC>" {
t.Fatalf("Expected '%s', got '%s'\n", "<SC><E>NUMBER</E></SC>", string(b))
}
}
func TestInv401kSource(t *testing.T) {
e, err := NewInv401kSource("PRETAX")
if err != nil {
t.Fatalf("Unexpected error creating new Inv401kSource from string \"PRETAX\"\n")
}
if !e.Valid() {
t.Fatalf("Inv401kSource unexpectedly invalid\n")
}
err = e.FromString("OTHERNONVEST")
if err != nil {
t.Fatalf("Unexpected error on Inv401kSource.FromString(\"OTHERNONVEST\")\n")
}
if e.String() != "OTHERNONVEST" {
t.Fatalf("Inv401kSource.String() expected to be \"OTHERNONVEST\"\n")
}
marshalHelper(t, "OTHERNONVEST", &e)
overwritten, err := NewInv401kSource("THISWILLNEVERBEAVALIDENUMSTRING")
if err == nil {
t.Fatalf("Expected error creating new Inv401kSource from string \"THISWILLNEVERBEAVALIDENUMSTRING\"\n")
}
if overwritten.Valid() {
t.Fatalf("Inv401kSource created with string \"THISWILLNEVERBEAVALIDENUMSTRING\" should not be valid\n")
}
if !strings.Contains(strings.ToLower(overwritten.String()), "invalid") {
t.Fatalf("Inv401kSource created with string \"THISWILLNEVERBEAVALIDENUMSTRING\" should not return valid string from String()\n")
}
b, err := xml.Marshal(&overwritten)
if err != nil {
t.Fatalf("Unexpected error on xml.Marshal(Inv401kSource): %s\n", err)
}
if string(b) != "" {
t.Fatalf("Expected empty string, got '%s'\n", string(b))
}
unmarshalHelper(t, "OTHERNONVEST", &e, &overwritten)
err = xml.Unmarshal([]byte("<GARBAGE><!LALDK>"), &overwritten)
if err == nil {
t.Fatalf("Expected error unmarshalling garbage value\n")
}
type SC struct {
E inv401kSource
}
sc := SC{E: e}
b, err = xml.Marshal(sc)
if err != nil {
t.Fatalf("Unexpected error on xml.Marshal(struct Inv401kSource): %s\n", err)
}
if string(b) != "<SC><E>OTHERNONVEST</E></SC>" {
t.Fatalf("Expected '%s', got '%s'\n", "<SC><E>OTHERNONVEST</E></SC>", string(b))
}
}
func TestSubAcctType(t *testing.T) {
e, err := NewSubAcctType("CASH")
if err != nil {
t.Fatalf("Unexpected error creating new SubAcctType from string \"CASH\"\n")
}
if !e.Valid() {
t.Fatalf("SubAcctType unexpectedly invalid\n")
}
err = e.FromString("OTHER")
if err != nil {
t.Fatalf("Unexpected error on SubAcctType.FromString(\"OTHER\")\n")
}
if e.String() != "OTHER" {
t.Fatalf("SubAcctType.String() expected to be \"OTHER\"\n")
}
marshalHelper(t, "OTHER", &e)
overwritten, err := NewSubAcctType("THISWILLNEVERBEAVALIDENUMSTRING")
if err == nil {
t.Fatalf("Expected error creating new SubAcctType from string \"THISWILLNEVERBEAVALIDENUMSTRING\"\n")
}
if overwritten.Valid() {
t.Fatalf("SubAcctType created with string \"THISWILLNEVERBEAVALIDENUMSTRING\" should not be valid\n")
}
if !strings.Contains(strings.ToLower(overwritten.String()), "invalid") {
t.Fatalf("SubAcctType created with string \"THISWILLNEVERBEAVALIDENUMSTRING\" should not return valid string from String()\n")
}
b, err := xml.Marshal(&overwritten)
if err != nil {
t.Fatalf("Unexpected error on xml.Marshal(SubAcctType): %s\n", err)
}
if string(b) != "" {
t.Fatalf("Expected empty string, got '%s'\n", string(b))
}
unmarshalHelper(t, "OTHER", &e, &overwritten)
err = xml.Unmarshal([]byte("<GARBAGE><!LALDK>"), &overwritten)
if err == nil {
t.Fatalf("Expected error unmarshalling garbage value\n")
}
type SC struct {
E subAcctType
}
sc := SC{E: e}
b, err = xml.Marshal(sc)
if err != nil {
t.Fatalf("Unexpected error on xml.Marshal(struct SubAcctType): %s\n", err)
}
if string(b) != "<SC><E>OTHER</E></SC>" {
t.Fatalf("Expected '%s', got '%s'\n", "<SC><E>OTHER</E></SC>", string(b))
}
}
func TestBuyType(t *testing.T) {
e, err := NewBuyType("BUY")
if err != nil {
t.Fatalf("Unexpected error creating new BuyType from string \"BUY\"\n")
}
if !e.Valid() {
t.Fatalf("BuyType unexpectedly invalid\n")
}
err = e.FromString("BUYTOCOVER")
if err != nil {
t.Fatalf("Unexpected error on BuyType.FromString(\"BUYTOCOVER\")\n")
}
if e.String() != "BUYTOCOVER" {
t.Fatalf("BuyType.String() expected to be \"BUYTOCOVER\"\n")
}
marshalHelper(t, "BUYTOCOVER", &e)
overwritten, err := NewBuyType("THISWILLNEVERBEAVALIDENUMSTRING")
if err == nil {
t.Fatalf("Expected error creating new BuyType from string \"THISWILLNEVERBEAVALIDENUMSTRING\"\n")
}
if overwritten.Valid() {
t.Fatalf("BuyType created with string \"THISWILLNEVERBEAVALIDENUMSTRING\" should not be valid\n")
}
if !strings.Contains(strings.ToLower(overwritten.String()), "invalid") {
t.Fatalf("BuyType created with string \"THISWILLNEVERBEAVALIDENUMSTRING\" should not return valid string from String()\n")
}
b, err := xml.Marshal(&overwritten)
if err != nil {
t.Fatalf("Unexpected error on xml.Marshal(BuyType): %s\n", err)
}
if string(b) != "" {
t.Fatalf("Expected empty string, got '%s'\n", string(b))
}
unmarshalHelper(t, "BUYTOCOVER", &e, &overwritten)
err = xml.Unmarshal([]byte("<GARBAGE><!LALDK>"), &overwritten)
if err == nil {
t.Fatalf("Expected error unmarshalling garbage value\n")
}
type SC struct {
E buyType
}
sc := SC{E: e}
b, err = xml.Marshal(sc)
if err != nil {
t.Fatalf("Unexpected error on xml.Marshal(struct BuyType): %s\n", err)
}
if string(b) != "<SC><E>BUYTOCOVER</E></SC>" {
t.Fatalf("Expected '%s', got '%s'\n", "<SC><E>BUYTOCOVER</E></SC>", string(b))
}
}
func TestOptAction(t *testing.T) {
e, err := NewOptAction("EXERCISE")
if err != nil {
t.Fatalf("Unexpected error creating new OptAction from string \"EXERCISE\"\n")
}
if !e.Valid() {
t.Fatalf("OptAction unexpectedly invalid\n")
}
err = e.FromString("EXPIRE")
if err != nil {
t.Fatalf("Unexpected error on OptAction.FromString(\"EXPIRE\")\n")
}
if e.String() != "EXPIRE" {
t.Fatalf("OptAction.String() expected to be \"EXPIRE\"\n")
}
marshalHelper(t, "EXPIRE", &e)
overwritten, err := NewOptAction("THISWILLNEVERBEAVALIDENUMSTRING")
if err == nil {
t.Fatalf("Expected error creating new OptAction from string \"THISWILLNEVERBEAVALIDENUMSTRING\"\n")
}
if overwritten.Valid() {
t.Fatalf("OptAction created with string \"THISWILLNEVERBEAVALIDENUMSTRING\" should not be valid\n")
}
if !strings.Contains(strings.ToLower(overwritten.String()), "invalid") {
t.Fatalf("OptAction created with string \"THISWILLNEVERBEAVALIDENUMSTRING\" should not return valid string from String()\n")
}
b, err := xml.Marshal(&overwritten)
if err != nil {
t.Fatalf("Unexpected error on xml.Marshal(OptAction): %s\n", err)
}
if string(b) != "" {
t.Fatalf("Expected empty string, got '%s'\n", string(b))
}
unmarshalHelper(t, "EXPIRE", &e, &overwritten)
err = xml.Unmarshal([]byte("<GARBAGE><!LALDK>"), &overwritten)
if err == nil {
t.Fatalf("Expected error unmarshalling garbage value\n")
}
type SC struct {
E optAction
}
sc := SC{E: e}
b, err = xml.Marshal(sc)
if err != nil {
t.Fatalf("Unexpected error on xml.Marshal(struct OptAction): %s\n", err)
}
if string(b) != "<SC><E>EXPIRE</E></SC>" {
t.Fatalf("Expected '%s', got '%s'\n", "<SC><E>EXPIRE</E></SC>", string(b))
}
}
func TestTferAction(t *testing.T) {
e, err := NewTferAction("IN")
if err != nil {
t.Fatalf("Unexpected error creating new TferAction from string \"IN\"\n")
}
if !e.Valid() {
t.Fatalf("TferAction unexpectedly invalid\n")
}
err = e.FromString("OUT")
if err != nil {
t.Fatalf("Unexpected error on TferAction.FromString(\"OUT\")\n")
}
if e.String() != "OUT" {
t.Fatalf("TferAction.String() expected to be \"OUT\"\n")
}
marshalHelper(t, "OUT", &e)
overwritten, err := NewTferAction("THISWILLNEVERBEAVALIDENUMSTRING")
if err == nil {
t.Fatalf("Expected error creating new TferAction from string \"THISWILLNEVERBEAVALIDENUMSTRING\"\n")
}
if overwritten.Valid() {
t.Fatalf("TferAction created with string \"THISWILLNEVERBEAVALIDENUMSTRING\" should not be valid\n")
}
if !strings.Contains(strings.ToLower(overwritten.String()), "invalid") {
t.Fatalf("TferAction created with string \"THISWILLNEVERBEAVALIDENUMSTRING\" should not return valid string from String()\n")
}
b, err := xml.Marshal(&overwritten)
if err != nil {
t.Fatalf("Unexpected error on xml.Marshal(TferAction): %s\n", err)
}
if string(b) != "" {
t.Fatalf("Expected empty string, got '%s'\n", string(b))
}
unmarshalHelper(t, "OUT", &e, &overwritten)
err = xml.Unmarshal([]byte("<GARBAGE><!LALDK>"), &overwritten)
if err == nil {
t.Fatalf("Expected error unmarshalling garbage value\n")
}
type SC struct {
E tferAction
}
sc := SC{E: e}
b, err = xml.Marshal(sc)
if err != nil {
t.Fatalf("Unexpected error on xml.Marshal(struct TferAction): %s\n", err)
}
if string(b) != "<SC><E>OUT</E></SC>" {
t.Fatalf("Expected '%s', got '%s'\n", "<SC><E>OUT</E></SC>", string(b))
}
}
func TestPosType(t *testing.T) {
e, err := NewPosType("LONG")
if err != nil {
t.Fatalf("Unexpected error creating new PosType from string \"LONG\"\n")
}
if !e.Valid() {
t.Fatalf("PosType unexpectedly invalid\n")
}
err = e.FromString("SHORT")
if err != nil {
t.Fatalf("Unexpected error on PosType.FromString(\"SHORT\")\n")
}
if e.String() != "SHORT" {
t.Fatalf("PosType.String() expected to be \"SHORT\"\n")
}
marshalHelper(t, "SHORT", &e)
overwritten, err := NewPosType("THISWILLNEVERBEAVALIDENUMSTRING")
if err == nil {
t.Fatalf("Expected error creating new PosType from string \"THISWILLNEVERBEAVALIDENUMSTRING\"\n")
}
if overwritten.Valid() {
t.Fatalf("PosType created with string \"THISWILLNEVERBEAVALIDENUMSTRING\" should not be valid\n")
}
if !strings.Contains(strings.ToLower(overwritten.String()), "invalid") {
t.Fatalf("PosType created with string \"THISWILLNEVERBEAVALIDENUMSTRING\" should not return valid string from String()\n")
}
b, err := xml.Marshal(&overwritten)
if err != nil {
t.Fatalf("Unexpected error on xml.Marshal(PosType): %s\n", err)
}
if string(b) != "" {
t.Fatalf("Expected empty string, got '%s'\n", string(b))
}
unmarshalHelper(t, "SHORT", &e, &overwritten)
err = xml.Unmarshal([]byte("<GARBAGE><!LALDK>"), &overwritten)
if err == nil {
t.Fatalf("Expected error unmarshalling garbage value\n")
}
type SC struct {
E posType
}
sc := SC{E: e}
b, err = xml.Marshal(sc)
if err != nil {
t.Fatalf("Unexpected error on xml.Marshal(struct PosType): %s\n", err)
}
if string(b) != "<SC><E>SHORT</E></SC>" {
t.Fatalf("Expected '%s', got '%s'\n", "<SC><E>SHORT</E></SC>", string(b))
}
}
func TestSecured(t *testing.T) {
e, err := NewSecured("NAKED")
if err != nil {
t.Fatalf("Unexpected error creating new Secured from string \"NAKED\"\n")
}
if !e.Valid() {
t.Fatalf("Secured unexpectedly invalid\n")
}
err = e.FromString("COVERED")
if err != nil {
t.Fatalf("Unexpected error on Secured.FromString(\"COVERED\")\n")
}
if e.String() != "COVERED" {
t.Fatalf("Secured.String() expected to be \"COVERED\"\n")
}
marshalHelper(t, "COVERED", &e)
overwritten, err := NewSecured("THISWILLNEVERBEAVALIDENUMSTRING")
if err == nil {
t.Fatalf("Expected error creating new Secured from string \"THISWILLNEVERBEAVALIDENUMSTRING\"\n")
}
if overwritten.Valid() {
t.Fatalf("Secured created with string \"THISWILLNEVERBEAVALIDENUMSTRING\" should not be valid\n")
}
if !strings.Contains(strings.ToLower(overwritten.String()), "invalid") {
t.Fatalf("Secured created with string \"THISWILLNEVERBEAVALIDENUMSTRING\" should not return valid string from String()\n")
}
b, err := xml.Marshal(&overwritten)
if err != nil {
t.Fatalf("Unexpected error on xml.Marshal(Secured): %s\n", err)
}
if string(b) != "" {
t.Fatalf("Expected empty string, got '%s'\n", string(b))
}
unmarshalHelper(t, "COVERED", &e, &overwritten)
err = xml.Unmarshal([]byte("<GARBAGE><!LALDK>"), &overwritten)
if err == nil {
t.Fatalf("Expected error unmarshalling garbage value\n")
}
type SC struct {
E secured
}
sc := SC{E: e}
b, err = xml.Marshal(sc)
if err != nil {
t.Fatalf("Unexpected error on xml.Marshal(struct Secured): %s\n", err)
}
if string(b) != "<SC><E>COVERED</E></SC>" {
t.Fatalf("Expected '%s', got '%s'\n", "<SC><E>COVERED</E></SC>", string(b))
}
}
func TestDuration(t *testing.T) {
e, err := NewDuration("DAY")
if err != nil {
t.Fatalf("Unexpected error creating new Duration from string \"DAY\"\n")
}
if !e.Valid() {
t.Fatalf("Duration unexpectedly invalid\n")
}
err = e.FromString("IMMEDIATE")
if err != nil {
t.Fatalf("Unexpected error on Duration.FromString(\"IMMEDIATE\")\n")
}
if e.String() != "IMMEDIATE" {
t.Fatalf("Duration.String() expected to be \"IMMEDIATE\"\n")
}
marshalHelper(t, "IMMEDIATE", &e)
overwritten, err := NewDuration("THISWILLNEVERBEAVALIDENUMSTRING")
if err == nil {
t.Fatalf("Expected error creating new Duration from string \"THISWILLNEVERBEAVALIDENUMSTRING\"\n")
}
if overwritten.Valid() {
t.Fatalf("Duration created with string \"THISWILLNEVERBEAVALIDENUMSTRING\" should not be valid\n")
}
if !strings.Contains(strings.ToLower(overwritten.String()), "invalid") {
t.Fatalf("Duration created with string \"THISWILLNEVERBEAVALIDENUMSTRING\" should not return valid string from String()\n")
}
b, err := xml.Marshal(&overwritten)
if err != nil {
t.Fatalf("Unexpected error on xml.Marshal(Duration): %s\n", err)
}
if string(b) != "" {
t.Fatalf("Expected empty string, got '%s'\n", string(b))
}
unmarshalHelper(t, "IMMEDIATE", &e, &overwritten)
err = xml.Unmarshal([]byte("<GARBAGE><!LALDK>"), &overwritten)
if err == nil {
t.Fatalf("Expected error unmarshalling garbage value\n")
}
type SC struct {
E duration
}
sc := SC{E: e}
b, err = xml.Marshal(sc)
if err != nil {
t.Fatalf("Unexpected error on xml.Marshal(struct Duration): %s\n", err)
}
if string(b) != "<SC><E>IMMEDIATE</E></SC>" {
t.Fatalf("Expected '%s', got '%s'\n", "<SC><E>IMMEDIATE</E></SC>", string(b))
}
}
func TestRestriction(t *testing.T) {
e, err := NewRestriction("ALLORNONE")
if err != nil {
t.Fatalf("Unexpected error creating new Restriction from string \"ALLORNONE\"\n")
}
if !e.Valid() {
t.Fatalf("Restriction unexpectedly invalid\n")
}
err = e.FromString("NONE")
if err != nil {
t.Fatalf("Unexpected error on Restriction.FromString(\"NONE\")\n")
}
if e.String() != "NONE" {
t.Fatalf("Restriction.String() expected to be \"NONE\"\n")
}
marshalHelper(t, "NONE", &e)
overwritten, err := NewRestriction("THISWILLNEVERBEAVALIDENUMSTRING")
if err == nil {
t.Fatalf("Expected error creating new Restriction from string \"THISWILLNEVERBEAVALIDENUMSTRING\"\n")
}
if overwritten.Valid() {
t.Fatalf("Restriction created with string \"THISWILLNEVERBEAVALIDENUMSTRING\" should not be valid\n")
}
if !strings.Contains(strings.ToLower(overwritten.String()), "invalid") {
t.Fatalf("Restriction created with string \"THISWILLNEVERBEAVALIDENUMSTRING\" should not return valid string from String()\n")
}
b, err := xml.Marshal(&overwritten)
if err != nil {
t.Fatalf("Unexpected error on xml.Marshal(Restriction): %s\n", err)
}
if string(b) != "" {
t.Fatalf("Expected empty string, got '%s'\n", string(b))
}
unmarshalHelper(t, "NONE", &e, &overwritten)
err = xml.Unmarshal([]byte("<GARBAGE><!LALDK>"), &overwritten)
if err == nil {
t.Fatalf("Expected error unmarshalling garbage value\n")
}
type SC struct {
E restriction
}
sc := SC{E: e}
b, err = xml.Marshal(sc)
if err != nil {
t.Fatalf("Unexpected error on xml.Marshal(struct Restriction): %s\n", err)
}
if string(b) != "<SC><E>NONE</E></SC>" {
t.Fatalf("Expected '%s', got '%s'\n", "<SC><E>NONE</E></SC>", string(b))
}
}
func TestUnitType(t *testing.T) {
e, err := NewUnitType("SHARES")
if err != nil {
t.Fatalf("Unexpected error creating new UnitType from string \"SHARES\"\n")
}
if !e.Valid() {
t.Fatalf("UnitType unexpectedly invalid\n")
}
err = e.FromString("CURRENCY")
if err != nil {
t.Fatalf("Unexpected error on UnitType.FromString(\"CURRENCY\")\n")
}
if e.String() != "CURRENCY" {
t.Fatalf("UnitType.String() expected to be \"CURRENCY\"\n")
}
marshalHelper(t, "CURRENCY", &e)
overwritten, err := NewUnitType("THISWILLNEVERBEAVALIDENUMSTRING")
if err == nil {
t.Fatalf("Expected error creating new UnitType from string \"THISWILLNEVERBEAVALIDENUMSTRING\"\n")
}
if overwritten.Valid() {
t.Fatalf("UnitType created with string \"THISWILLNEVERBEAVALIDENUMSTRING\" should not be valid\n")
}
if !strings.Contains(strings.ToLower(overwritten.String()), "invalid") {
t.Fatalf("UnitType created with string \"THISWILLNEVERBEAVALIDENUMSTRING\" should not return valid string from String()\n")
}
b, err := xml.Marshal(&overwritten)
if err != nil {
t.Fatalf("Unexpected error on xml.Marshal(UnitType): %s\n", err)
}
if string(b) != "" {
t.Fatalf("Expected empty string, got '%s'\n", string(b))
}
unmarshalHelper(t, "CURRENCY", &e, &overwritten)
err = xml.Unmarshal([]byte("<GARBAGE><!LALDK>"), &overwritten)
if err == nil {
t.Fatalf("Expected error unmarshalling garbage value\n")
}
type SC struct {
E unitType
}
sc := SC{E: e}
b, err = xml.Marshal(sc)
if err != nil {
t.Fatalf("Unexpected error on xml.Marshal(struct UnitType): %s\n", err)
}
if string(b) != "<SC><E>CURRENCY</E></SC>" {
t.Fatalf("Expected '%s', got '%s'\n", "<SC><E>CURRENCY</E></SC>", string(b))
}
}
func TestOptBuyType(t *testing.T) {
e, err := NewOptBuyType("BUYTOOPEN")
if err != nil {
t.Fatalf("Unexpected error creating new OptBuyType from string \"BUYTOOPEN\"\n")
}
if !e.Valid() {
t.Fatalf("OptBuyType unexpectedly invalid\n")
}
err = e.FromString("BUYTOCLOSE")
if err != nil {
t.Fatalf("Unexpected error on OptBuyType.FromString(\"BUYTOCLOSE\")\n")
}
if e.String() != "BUYTOCLOSE" {
t.Fatalf("OptBuyType.String() expected to be \"BUYTOCLOSE\"\n")
}
marshalHelper(t, "BUYTOCLOSE", &e)
overwritten, err := NewOptBuyType("THISWILLNEVERBEAVALIDENUMSTRING")
if err == nil {
t.Fatalf("Expected error creating new OptBuyType from string \"THISWILLNEVERBEAVALIDENUMSTRING\"\n")
}
if overwritten.Valid() {
t.Fatalf("OptBuyType created with string \"THISWILLNEVERBEAVALIDENUMSTRING\" should not be valid\n")
}
if !strings.Contains(strings.ToLower(overwritten.String()), "invalid") {
t.Fatalf("OptBuyType created with string \"THISWILLNEVERBEAVALIDENUMSTRING\" should not return valid string from String()\n")
}
b, err := xml.Marshal(&overwritten)
if err != nil {
t.Fatalf("Unexpected error on xml.Marshal(OptBuyType): %s\n", err)
}
if string(b) != "" {
t.Fatalf("Expected empty string, got '%s'\n", string(b))
}
unmarshalHelper(t, "BUYTOCLOSE", &e, &overwritten)
err = xml.Unmarshal([]byte("<GARBAGE><!LALDK>"), &overwritten)
if err == nil {
t.Fatalf("Expected error unmarshalling garbag
gitextract_ipheoeo0/ ├── .github/ │ └── workflows/ │ └── test.yml ├── LICENSE ├── README.md ├── bank.go ├── bank_test.go ├── basic_client.go ├── basic_client_test.go ├── client.go ├── cmd/ │ └── ofx/ │ ├── bankdownload.go │ ├── banktransactions.go │ ├── ccdownload.go │ ├── cctransactions.go │ ├── command.go │ ├── detect_settings.go │ ├── get_accounts.go │ ├── invdownload.go │ ├── invtransactions.go │ ├── main.go │ ├── profiledownload.go │ └── util.go ├── common.go ├── common_test.go ├── constants.go ├── constants_test.go ├── creditcard.go ├── creditcard_test.go ├── discovercard_client.go ├── doc.go ├── generate_constants.py ├── go.mod ├── go.sum ├── invstmt.go ├── invstmt_test.go ├── leaf_elements.go ├── profile.go ├── profile_test.go ├── request.go ├── request_test.go ├── response.go ├── response_test.go ├── samples/ │ ├── busted_responses/ │ │ ├── bmo_v102__no_header_newline.qfx │ │ └── wellsfargo.qfx │ └── valid_responses/ │ ├── 401k_v203.ofx │ ├── inv_v202.ofx │ ├── ira_v202.ofx │ ├── moneymrkt1_v103.ofx │ ├── moneymrkt1_v103_TYPE1.ofx │ └── moneymrkt1_v203.ofx ├── seclist.go ├── signon.go ├── signon_test.go ├── signup.go ├── signup_test.go ├── types.go ├── types_test.go ├── util.go └── vanguard_client.go
SYMBOL INDEX (946 symbols across 41 files)
FILE: bank.go
type StatementRequest (line 12) | type StatementRequest struct
method Name (line 27) | func (r *StatementRequest) Name() string {
method Valid (line 33) | func (r *StatementRequest) Valid(version ofxVersion) (bool, error) {
method Type (line 48) | func (r *StatementRequest) Type() messageType {
type Payee (line 53) | type Payee struct
method Valid (line 67) | func (p Payee) Valid() (bool, error) {
type ImageData (line 88) | type ImageData struct
type Transaction (line 104) | type Transaction struct
method Valid (line 135) | func (t Transaction) Valid(version ofxVersion) (bool, error) {
type TransactionList (line 184) | type TransactionList struct
method Valid (line 192) | func (l TransactionList) Valid(version ofxVersion) (bool, error) {
type PendingTransaction (line 211) | type PendingTransaction struct
method Valid (line 229) | func (t PendingTransaction) Valid() (bool, error) {
type PendingTransactionList (line 248) | type PendingTransactionList struct
method Valid (line 255) | func (l PendingTransactionList) Valid() (bool, error) {
type Balance (line 270) | type Balance struct
method Valid (line 287) | func (b Balance) Valid() (bool, error) {
type StatementResponse (line 300) | type StatementResponse struct
method Name (line 321) | func (sr *StatementResponse) Name() string {
method Valid (line 326) | func (sr *StatementResponse) Valid(version ofxVersion) (bool, error) {
method Type (line 364) | func (sr *StatementResponse) Type() messageType {
FILE: bank_test.go
function TestMarshalBankStatementRequest (line 9) | func TestMarshalBankStatementRequest(t *testing.T) {
function TestMarshalBankStatementRequest103 (line 75) | func TestMarshalBankStatementRequest103(t *testing.T) {
function TestUnmarshalBankStatementResponse (line 149) | func TestUnmarshalBankStatementResponse(t *testing.T) {
function TestPayeeValid (line 288) | func TestPayeeValid(t *testing.T) {
function TestBalanceValid (line 346) | func TestBalanceValid(t *testing.T) {
FILE: basic_client.go
type BasicClient (line 13) | type BasicClient struct
method OfxVersion (line 32) | func (c *BasicClient) OfxVersion() ofxVersion {
method ID (line 41) | func (c *BasicClient) ID() String {
method Version (line 50) | func (c *BasicClient) Version() String {
method IndentRequests (line 59) | func (c *BasicClient) IndentRequests() bool {
method CarriageReturnNewLines (line 64) | func (c *BasicClient) CarriageReturnNewLines() bool {
method RawRequest (line 70) | func (c *BasicClient) RawRequest(URL string, r io.Reader) (*http.Respo...
method RequestNoParse (line 103) | func (c *BasicClient) RequestNoParse(r *Request) (*http.Response, erro...
method Request (line 109) | func (c *BasicClient) Request(r *Request) (*Response, error) {
FILE: basic_client_test.go
function TestBasicClient_HTTPClient (line 11) | func TestBasicClient_HTTPClient(t *testing.T) {
FILE: client.go
type Client (line 13) | type Client interface
type clientCreationFunc (line 57) | type clientCreationFunc
function GetClient (line 62) | func GetClient(URL string, bc *BasicClient) Client {
function clientRequestNoParse (line 80) | func clientRequestNoParse(c Client, r *Request) (*http.Response, error) {
function clientRequest (line 93) | func clientRequest(c Client, r *Request) (*Response, error) {
FILE: cmd/ofx/bankdownload.go
function init (line 21) | func init() {
function downloadCheckFlags (line 29) | func downloadCheckFlags() bool {
function download (line 40) | func download() {
FILE: cmd/ofx/banktransactions.go
function init (line 18) | func init() {
function bankTransactions (line 25) | func bankTransactions() {
function printTransaction (line 83) | func printTransaction(defCurrency ofxgo.CurrSymbol, tran *ofxgo.Transact...
FILE: cmd/ofx/ccdownload.go
function init (line 19) | func init() {
function ccDownloadCheckFlags (line 25) | func ccDownloadCheckFlags() bool {
function ccDownload (line 36) | func ccDownload() {
FILE: cmd/ofx/cctransactions.go
function init (line 18) | func init() {
function ccTransactions (line 23) | func ccTransactions() {
FILE: cmd/ofx/command.go
type command (line 10) | type command struct
method usage (line 18) | func (c *command) usage() {
function defineServerFlags (line 30) | func defineServerFlags(f *flag.FlagSet) {
function checkServerFlags (line 46) | func checkServerFlags() bool {
FILE: cmd/ofx/detect_settings.go
function init (line 21) | func init() {
function detectSettings (line 95) | func detectSettings() {
constant anonymous (line 123) | anonymous = "anonymous00000000000000000000000"
function tryProfile (line 125) | func tryProfile(appID, appVer, version string, noindent bool) bool {
FILE: cmd/ofx/get_accounts.go
function init (line 19) | func init() {
function getAccounts (line 23) | func getAccounts() {
FILE: cmd/ofx/invdownload.go
function init (line 21) | func init() {
function invDownloadCheckFlags (line 28) | func invDownloadCheckFlags() bool {
function invDownload (line 39) | func invDownload() {
FILE: cmd/ofx/invtransactions.go
function init (line 18) | func init() {
function invTransactions (line 24) | func invTransactions() {
function printInvTran (line 170) | func printInvTran(it *ofxgo.InvTran) {
function printInvBuy (line 174) | func printInvBuy(defCurrency ofxgo.CurrSymbol, ib *ofxgo.InvBuy) {
function printInvSell (line 185) | func printInvSell(defCurrency ofxgo.CurrSymbol, is *ofxgo.InvSell) {
FILE: cmd/ofx/main.go
function usage (line 21) | func usage() {
function runCmd (line 43) | func runCmd(c *command) {
function main (line 60) | func main() {
FILE: cmd/ofx/profiledownload.go
function init (line 19) | func init() {
function downloadProfileCheckFlags (line 24) | func downloadProfileCheckFlags() bool {
function downloadProfile (line 42) | func downloadProfile() {
FILE: cmd/ofx/util.go
function newRequest (line 9) | func newRequest() (ofxgo.Client, *ofxgo.Request) {
function printRequest (line 36) | func printRequest(c ofxgo.Client, r *ofxgo.Request) {
FILE: common.go
function writeHeader (line 14) | func writeHeader(b *bytes.Buffer, v ofxVersion, carriageReturn bool) err...
type Message (line 52) | type Message interface
type messageType (line 58) | type messageType
method String (line 98) | func (t messageType) String() string {
constant SignonRq (line 64) | SignonRq messageType = iota
constant SignupRq (line 65) | SignupRq
constant BankRq (line 66) | BankRq
constant CreditCardRq (line 67) | CreditCardRq
constant LoanRq (line 68) | LoanRq
constant InvStmtRq (line 69) | InvStmtRq
constant InterXferRq (line 70) | InterXferRq
constant WireXferRq (line 71) | WireXferRq
constant BillpayRq (line 72) | BillpayRq
constant EmailRq (line 73) | EmailRq
constant SecListRq (line 74) | SecListRq
constant PresDirRq (line 75) | PresDirRq
constant PresDlvRq (line 76) | PresDlvRq
constant ProfRq (line 77) | ProfRq
constant ImageRq (line 78) | ImageRq
constant SignonRs (line 81) | SignonRs
constant SignupRs (line 82) | SignupRs
constant BankRs (line 83) | BankRs
constant CreditCardRs (line 84) | CreditCardRs
constant LoanRs (line 85) | LoanRs
constant InvStmtRs (line 86) | InvStmtRs
constant InterXferRs (line 87) | InterXferRs
constant WireXferRs (line 88) | WireXferRs
constant BillpayRs (line 89) | BillpayRs
constant EmailRs (line 90) | EmailRs
constant SecListRs (line 91) | SecListRs
constant PresDirRs (line 92) | PresDirRs
constant PresDlvRs (line 93) | PresDlvRs
constant ProfRs (line 94) | ProfRs
constant ImageRs (line 95) | ImageRs
type Status (line 264) | type Status struct
method Valid (line 272) | func (s *Status) Valid() (bool, error) {
method CodeMeaning (line 291) | func (s *Status) CodeMeaning() (string, error) {
method CodeConditions (line 300) | func (s *Status) CodeConditions() (string, error) {
type BankAcct (line 308) | type BankAcct struct
method Valid (line 318) | func (b BankAcct) Valid() (bool, error) {
type CCAcct (line 332) | type CCAcct struct
method Valid (line 339) | func (c CCAcct) Valid() (bool, error) {
type InvAcct (line 347) | type InvAcct struct
type Currency (line 358) | type Currency struct
method Valid (line 365) | func (c Currency) Valid() (bool, error) {
FILE: common_test.go
function TestStatusValid (line 7) | func TestStatusValid(t *testing.T) {
function TestStatusCodeMeaning (line 33) | func TestStatusCodeMeaning(t *testing.T) {
function TestStatusCodeConditions (line 52) | func TestStatusCodeConditions(t *testing.T) {
FILE: constants.go
type ofxVersion (line 17) | type ofxVersion
method Valid (line 36) | func (e ofxVersion) Valid() bool {
method String (line 42) | func (e ofxVersion) String() string {
method FromString (line 49) | func (e *ofxVersion) FromString(in string) error {
method UnmarshalXML (line 62) | func (e *ofxVersion) UnmarshalXML(d *xml.Decoder, start xml.StartEleme...
method MarshalXML (line 72) | func (e ofxVersion) MarshalXML(enc *xml.Encoder, start xml.StartElemen...
constant OfxVersion102 (line 21) | OfxVersion102 ofxVersion = 1 + iota
constant OfxVersion103 (line 22) | OfxVersion103
constant OfxVersion151 (line 23) | OfxVersion151
constant OfxVersion160 (line 24) | OfxVersion160
constant OfxVersion200 (line 25) | OfxVersion200
constant OfxVersion201 (line 26) | OfxVersion201
constant OfxVersion202 (line 27) | OfxVersion202
constant OfxVersion203 (line 28) | OfxVersion203
constant OfxVersion210 (line 29) | OfxVersion210
constant OfxVersion211 (line 30) | OfxVersion211
constant OfxVersion220 (line 31) | OfxVersion220
function NewOfxVersion (line 82) | func NewOfxVersion(s string) (ofxVersion, error) {
type acctType (line 91) | type acctType
method Valid (line 104) | func (e acctType) Valid() bool {
method String (line 110) | func (e acctType) String() string {
method FromString (line 117) | func (e *acctType) FromString(in string) error {
method UnmarshalXML (line 130) | func (e *acctType) UnmarshalXML(d *xml.Decoder, start xml.StartElement...
method MarshalXML (line 140) | func (e acctType) MarshalXML(enc *xml.Encoder, start xml.StartElement)...
constant AcctTypeChecking (line 95) | AcctTypeChecking acctType = 1 + iota
constant AcctTypeSavings (line 96) | AcctTypeSavings
constant AcctTypeMoneyMrkt (line 97) | AcctTypeMoneyMrkt
constant AcctTypeCreditLine (line 98) | AcctTypeCreditLine
constant AcctTypeCD (line 99) | AcctTypeCD
function NewAcctType (line 150) | func NewAcctType(s string) (acctType, error) {
type trnType (line 159) | type trnType
method Valid (line 185) | func (e trnType) Valid() bool {
method String (line 191) | func (e trnType) String() string {
method FromString (line 198) | func (e *trnType) FromString(in string) error {
method UnmarshalXML (line 211) | func (e *trnType) UnmarshalXML(d *xml.Decoder, start xml.StartElement)...
method MarshalXML (line 221) | func (e trnType) MarshalXML(enc *xml.Encoder, start xml.StartElement) ...
constant TrnTypeCredit (line 163) | TrnTypeCredit trnType = 1 + iota
constant TrnTypeDebit (line 164) | TrnTypeDebit
constant TrnTypeInt (line 165) | TrnTypeInt
constant TrnTypeDiv (line 166) | TrnTypeDiv
constant TrnTypeFee (line 167) | TrnTypeFee
constant TrnTypeSrvChg (line 168) | TrnTypeSrvChg
constant TrnTypeDep (line 169) | TrnTypeDep
constant TrnTypeATM (line 170) | TrnTypeATM
constant TrnTypePOS (line 171) | TrnTypePOS
constant TrnTypeXfer (line 172) | TrnTypeXfer
constant TrnTypeCheck (line 173) | TrnTypeCheck
constant TrnTypePayment (line 174) | TrnTypePayment
constant TrnTypeCash (line 175) | TrnTypeCash
constant TrnTypeDirectDep (line 176) | TrnTypeDirectDep
constant TrnTypeDirectDebit (line 177) | TrnTypeDirectDebit
constant TrnTypeRepeatPmt (line 178) | TrnTypeRepeatPmt
constant TrnTypeHold (line 179) | TrnTypeHold
constant TrnTypeOther (line 180) | TrnTypeOther
function NewTrnType (line 231) | func NewTrnType(s string) (trnType, error) {
type imageType (line 240) | type imageType
method Valid (line 251) | func (e imageType) Valid() bool {
method String (line 257) | func (e imageType) String() string {
method FromString (line 264) | func (e *imageType) FromString(in string) error {
method UnmarshalXML (line 277) | func (e *imageType) UnmarshalXML(d *xml.Decoder, start xml.StartElemen...
method MarshalXML (line 287) | func (e imageType) MarshalXML(enc *xml.Encoder, start xml.StartElement...
constant ImageTypeStatement (line 244) | ImageTypeStatement imageType = 1 + iota
constant ImageTypeTransaction (line 245) | ImageTypeTransaction
constant ImageTypeTax (line 246) | ImageTypeTax
function NewImageType (line 297) | func NewImageType(s string) (imageType, error) {
type imageRefType (line 306) | type imageRefType
method Valid (line 317) | func (e imageRefType) Valid() bool {
method String (line 323) | func (e imageRefType) String() string {
method FromString (line 330) | func (e *imageRefType) FromString(in string) error {
method UnmarshalXML (line 343) | func (e *imageRefType) UnmarshalXML(d *xml.Decoder, start xml.StartEle...
method MarshalXML (line 353) | func (e imageRefType) MarshalXML(enc *xml.Encoder, start xml.StartElem...
constant ImageRefTypeOpaque (line 310) | ImageRefTypeOpaque imageRefType = 1 + iota
constant ImageRefTypeURL (line 311) | ImageRefTypeURL
constant ImageRefTypeFormURL (line 312) | ImageRefTypeFormURL
function NewImageRefType (line 363) | func NewImageRefType(s string) (imageRefType, error) {
type checkSup (line 372) | type checkSup
method Valid (line 383) | func (e checkSup) Valid() bool {
method String (line 389) | func (e checkSup) String() string {
method FromString (line 396) | func (e *checkSup) FromString(in string) error {
method UnmarshalXML (line 409) | func (e *checkSup) UnmarshalXML(d *xml.Decoder, start xml.StartElement...
method MarshalXML (line 419) | func (e checkSup) MarshalXML(enc *xml.Encoder, start xml.StartElement)...
constant CheckSupFrontOnly (line 376) | CheckSupFrontOnly checkSup = 1 + iota
constant CheckSupBackOnly (line 377) | CheckSupBackOnly
constant CheckSupFrontAndBack (line 378) | CheckSupFrontAndBack
function NewCheckSup (line 429) | func NewCheckSup(s string) (checkSup, error) {
type correctAction (line 438) | type correctAction
method Valid (line 448) | func (e correctAction) Valid() bool {
method String (line 454) | func (e correctAction) String() string {
method FromString (line 461) | func (e *correctAction) FromString(in string) error {
method UnmarshalXML (line 474) | func (e *correctAction) UnmarshalXML(d *xml.Decoder, start xml.StartEl...
method MarshalXML (line 484) | func (e correctAction) MarshalXML(enc *xml.Encoder, start xml.StartEle...
constant CorrectActionDelete (line 442) | CorrectActionDelete correctAction = 1 + iota
constant CorrectActionReplace (line 443) | CorrectActionReplace
function NewCorrectAction (line 494) | func NewCorrectAction(s string) (correctAction, error) {
type balType (line 503) | type balType
method Valid (line 514) | func (e balType) Valid() bool {
method String (line 520) | func (e balType) String() string {
method FromString (line 527) | func (e *balType) FromString(in string) error {
method UnmarshalXML (line 540) | func (e *balType) UnmarshalXML(d *xml.Decoder, start xml.StartElement)...
method MarshalXML (line 550) | func (e balType) MarshalXML(enc *xml.Encoder, start xml.StartElement) ...
constant BalTypeDollar (line 507) | BalTypeDollar balType = 1 + iota
constant BalTypePercent (line 508) | BalTypePercent
constant BalTypeNumber (line 509) | BalTypeNumber
function NewBalType (line 560) | func NewBalType(s string) (balType, error) {
type inv401kSource (line 569) | type inv401kSource
method Valid (line 584) | func (e inv401kSource) Valid() bool {
method String (line 590) | func (e inv401kSource) String() string {
method FromString (line 597) | func (e *inv401kSource) FromString(in string) error {
method UnmarshalXML (line 610) | func (e *inv401kSource) UnmarshalXML(d *xml.Decoder, start xml.StartEl...
method MarshalXML (line 620) | func (e inv401kSource) MarshalXML(enc *xml.Encoder, start xml.StartEle...
constant Inv401kSourcePreTax (line 573) | Inv401kSourcePreTax inv401kSource = 1 + iota
constant Inv401kSourceAfterTax (line 574) | Inv401kSourceAfterTax
constant Inv401kSourceMatch (line 575) | Inv401kSourceMatch
constant Inv401kSourceProfitSharing (line 576) | Inv401kSourceProfitSharing
constant Inv401kSourceRollover (line 577) | Inv401kSourceRollover
constant Inv401kSourceOtherVest (line 578) | Inv401kSourceOtherVest
constant Inv401kSourceOtherNonVest (line 579) | Inv401kSourceOtherNonVest
function NewInv401kSource (line 630) | func NewInv401kSource(s string) (inv401kSource, error) {
type subAcctType (line 639) | type subAcctType
method Valid (line 651) | func (e subAcctType) Valid() bool {
method String (line 657) | func (e subAcctType) String() string {
method FromString (line 664) | func (e *subAcctType) FromString(in string) error {
method UnmarshalXML (line 677) | func (e *subAcctType) UnmarshalXML(d *xml.Decoder, start xml.StartElem...
method MarshalXML (line 687) | func (e subAcctType) MarshalXML(enc *xml.Encoder, start xml.StartEleme...
constant SubAcctTypeCash (line 643) | SubAcctTypeCash subAcctType = 1 + iota
constant SubAcctTypeMargin (line 644) | SubAcctTypeMargin
constant SubAcctTypeShort (line 645) | SubAcctTypeShort
constant SubAcctTypeOther (line 646) | SubAcctTypeOther
function NewSubAcctType (line 697) | func NewSubAcctType(s string) (subAcctType, error) {
type buyType (line 706) | type buyType
method Valid (line 716) | func (e buyType) Valid() bool {
method String (line 722) | func (e buyType) String() string {
method FromString (line 729) | func (e *buyType) FromString(in string) error {
method UnmarshalXML (line 742) | func (e *buyType) UnmarshalXML(d *xml.Decoder, start xml.StartElement)...
method MarshalXML (line 752) | func (e buyType) MarshalXML(enc *xml.Encoder, start xml.StartElement) ...
constant BuyTypeBuy (line 710) | BuyTypeBuy buyType = 1 + iota
constant BuyTypeBuyToCover (line 711) | BuyTypeBuyToCover
function NewBuyType (line 762) | func NewBuyType(s string) (buyType, error) {
type optAction (line 771) | type optAction
method Valid (line 782) | func (e optAction) Valid() bool {
method String (line 788) | func (e optAction) String() string {
method FromString (line 795) | func (e *optAction) FromString(in string) error {
method UnmarshalXML (line 808) | func (e *optAction) UnmarshalXML(d *xml.Decoder, start xml.StartElemen...
method MarshalXML (line 818) | func (e optAction) MarshalXML(enc *xml.Encoder, start xml.StartElement...
constant OptActionExercise (line 775) | OptActionExercise optAction = 1 + iota
constant OptActionAssign (line 776) | OptActionAssign
constant OptActionExpire (line 777) | OptActionExpire
function NewOptAction (line 828) | func NewOptAction(s string) (optAction, error) {
type tferAction (line 837) | type tferAction
method Valid (line 847) | func (e tferAction) Valid() bool {
method String (line 853) | func (e tferAction) String() string {
method FromString (line 860) | func (e *tferAction) FromString(in string) error {
method UnmarshalXML (line 873) | func (e *tferAction) UnmarshalXML(d *xml.Decoder, start xml.StartEleme...
method MarshalXML (line 883) | func (e tferAction) MarshalXML(enc *xml.Encoder, start xml.StartElemen...
constant TferActionIn (line 841) | TferActionIn tferAction = 1 + iota
constant TferActionOut (line 842) | TferActionOut
function NewTferAction (line 893) | func NewTferAction(s string) (tferAction, error) {
type posType (line 902) | type posType
method Valid (line 912) | func (e posType) Valid() bool {
method String (line 918) | func (e posType) String() string {
method FromString (line 925) | func (e *posType) FromString(in string) error {
method UnmarshalXML (line 938) | func (e *posType) UnmarshalXML(d *xml.Decoder, start xml.StartElement)...
method MarshalXML (line 948) | func (e posType) MarshalXML(enc *xml.Encoder, start xml.StartElement) ...
constant PosTypeLong (line 906) | PosTypeLong posType = 1 + iota
constant PosTypeShort (line 907) | PosTypeShort
function NewPosType (line 958) | func NewPosType(s string) (posType, error) {
type secured (line 967) | type secured
method Valid (line 977) | func (e secured) Valid() bool {
method String (line 983) | func (e secured) String() string {
method FromString (line 990) | func (e *secured) FromString(in string) error {
method UnmarshalXML (line 1003) | func (e *secured) UnmarshalXML(d *xml.Decoder, start xml.StartElement)...
method MarshalXML (line 1013) | func (e secured) MarshalXML(enc *xml.Encoder, start xml.StartElement) ...
constant SecuredNaked (line 971) | SecuredNaked secured = 1 + iota
constant SecuredCovered (line 972) | SecuredCovered
function NewSecured (line 1023) | func NewSecured(s string) (secured, error) {
type duration (line 1032) | type duration
method Valid (line 1043) | func (e duration) Valid() bool {
method String (line 1049) | func (e duration) String() string {
method FromString (line 1056) | func (e *duration) FromString(in string) error {
method UnmarshalXML (line 1069) | func (e *duration) UnmarshalXML(d *xml.Decoder, start xml.StartElement...
method MarshalXML (line 1079) | func (e duration) MarshalXML(enc *xml.Encoder, start xml.StartElement)...
constant DurationDay (line 1036) | DurationDay duration = 1 + iota
constant DurationGoodTilCancel (line 1037) | DurationGoodTilCancel
constant DurationImmediate (line 1038) | DurationImmediate
function NewDuration (line 1089) | func NewDuration(s string) (duration, error) {
type restriction (line 1098) | type restriction
method Valid (line 1109) | func (e restriction) Valid() bool {
method String (line 1115) | func (e restriction) String() string {
method FromString (line 1122) | func (e *restriction) FromString(in string) error {
method UnmarshalXML (line 1135) | func (e *restriction) UnmarshalXML(d *xml.Decoder, start xml.StartElem...
method MarshalXML (line 1145) | func (e restriction) MarshalXML(enc *xml.Encoder, start xml.StartEleme...
constant RestrictionAllOrNone (line 1102) | RestrictionAllOrNone restriction = 1 + iota
constant RestrictionMinUnits (line 1103) | RestrictionMinUnits
constant RestrictionNone (line 1104) | RestrictionNone
function NewRestriction (line 1155) | func NewRestriction(s string) (restriction, error) {
type unitType (line 1164) | type unitType
method Valid (line 1174) | func (e unitType) Valid() bool {
method String (line 1180) | func (e unitType) String() string {
method FromString (line 1187) | func (e *unitType) FromString(in string) error {
method UnmarshalXML (line 1200) | func (e *unitType) UnmarshalXML(d *xml.Decoder, start xml.StartElement...
method MarshalXML (line 1210) | func (e unitType) MarshalXML(enc *xml.Encoder, start xml.StartElement)...
constant UnitTypeShares (line 1168) | UnitTypeShares unitType = 1 + iota
constant UnitTypeCurrency (line 1169) | UnitTypeCurrency
function NewUnitType (line 1220) | func NewUnitType(s string) (unitType, error) {
type optBuyType (line 1229) | type optBuyType
method Valid (line 1239) | func (e optBuyType) Valid() bool {
method String (line 1245) | func (e optBuyType) String() string {
method FromString (line 1252) | func (e *optBuyType) FromString(in string) error {
method UnmarshalXML (line 1265) | func (e *optBuyType) UnmarshalXML(d *xml.Decoder, start xml.StartEleme...
method MarshalXML (line 1275) | func (e optBuyType) MarshalXML(enc *xml.Encoder, start xml.StartElemen...
constant OptBuyTypeBuyToOpen (line 1233) | OptBuyTypeBuyToOpen optBuyType = 1 + iota
constant OptBuyTypeBuyToClose (line 1234) | OptBuyTypeBuyToClose
function NewOptBuyType (line 1285) | func NewOptBuyType(s string) (optBuyType, error) {
type sellType (line 1294) | type sellType
method Valid (line 1304) | func (e sellType) Valid() bool {
method String (line 1310) | func (e sellType) String() string {
method FromString (line 1317) | func (e *sellType) FromString(in string) error {
method UnmarshalXML (line 1330) | func (e *sellType) UnmarshalXML(d *xml.Decoder, start xml.StartElement...
method MarshalXML (line 1340) | func (e sellType) MarshalXML(enc *xml.Encoder, start xml.StartElement)...
constant SellTypeSell (line 1298) | SellTypeSell sellType = 1 + iota
constant SellTypeSellShort (line 1299) | SellTypeSellShort
function NewSellType (line 1350) | func NewSellType(s string) (sellType, error) {
type loanPmtFreq (line 1359) | type loanPmtFreq
method Valid (line 1377) | func (e loanPmtFreq) Valid() bool {
method String (line 1383) | func (e loanPmtFreq) String() string {
method FromString (line 1390) | func (e *loanPmtFreq) FromString(in string) error {
method UnmarshalXML (line 1403) | func (e *loanPmtFreq) UnmarshalXML(d *xml.Decoder, start xml.StartElem...
method MarshalXML (line 1413) | func (e loanPmtFreq) MarshalXML(enc *xml.Encoder, start xml.StartEleme...
constant LoanPmtFreqWeekly (line 1363) | LoanPmtFreqWeekly loanPmtFreq = 1 + iota
constant LoanPmtFreqBiweekly (line 1364) | LoanPmtFreqBiweekly
constant LoanPmtFreqTwiceMonthly (line 1365) | LoanPmtFreqTwiceMonthly
constant LoanPmtFreqMonthly (line 1366) | LoanPmtFreqMonthly
constant LoanPmtFreqFourWeeks (line 1367) | LoanPmtFreqFourWeeks
constant LoanPmtFreqBiMonthly (line 1368) | LoanPmtFreqBiMonthly
constant LoanPmtFreqQuarterly (line 1369) | LoanPmtFreqQuarterly
constant LoanPmtFreqSemiannually (line 1370) | LoanPmtFreqSemiannually
constant LoanPmtFreqAnnually (line 1371) | LoanPmtFreqAnnually
constant LoanPmtFreqOther (line 1372) | LoanPmtFreqOther
function NewLoanPmtFreq (line 1423) | func NewLoanPmtFreq(s string) (loanPmtFreq, error) {
type incomeType (line 1432) | type incomeType
method Valid (line 1445) | func (e incomeType) Valid() bool {
method String (line 1451) | func (e incomeType) String() string {
method FromString (line 1458) | func (e *incomeType) FromString(in string) error {
method UnmarshalXML (line 1471) | func (e *incomeType) UnmarshalXML(d *xml.Decoder, start xml.StartEleme...
method MarshalXML (line 1481) | func (e incomeType) MarshalXML(enc *xml.Encoder, start xml.StartElemen...
constant IncomeTypeCGLong (line 1436) | IncomeTypeCGLong incomeType = 1 + iota
constant IncomeTypeCGShort (line 1437) | IncomeTypeCGShort
constant IncomeTypeDiv (line 1438) | IncomeTypeDiv
constant IncomeTypeInterest (line 1439) | IncomeTypeInterest
constant IncomeTypeMisc (line 1440) | IncomeTypeMisc
function NewIncomeType (line 1491) | func NewIncomeType(s string) (incomeType, error) {
type sellReason (line 1500) | type sellReason
method Valid (line 1511) | func (e sellReason) Valid() bool {
method String (line 1517) | func (e sellReason) String() string {
method FromString (line 1524) | func (e *sellReason) FromString(in string) error {
method UnmarshalXML (line 1537) | func (e *sellReason) UnmarshalXML(d *xml.Decoder, start xml.StartEleme...
method MarshalXML (line 1547) | func (e sellReason) MarshalXML(enc *xml.Encoder, start xml.StartElemen...
constant SellReasonCall (line 1504) | SellReasonCall sellReason = 1 + iota
constant SellReasonSell (line 1505) | SellReasonSell
constant SellReasonMaturity (line 1506) | SellReasonMaturity
function NewSellReason (line 1557) | func NewSellReason(s string) (sellReason, error) {
type optSellType (line 1566) | type optSellType
method Valid (line 1576) | func (e optSellType) Valid() bool {
method String (line 1582) | func (e optSellType) String() string {
method FromString (line 1589) | func (e *optSellType) FromString(in string) error {
method UnmarshalXML (line 1602) | func (e *optSellType) UnmarshalXML(d *xml.Decoder, start xml.StartElem...
method MarshalXML (line 1612) | func (e optSellType) MarshalXML(enc *xml.Encoder, start xml.StartEleme...
constant OptSellTypeSellToClose (line 1570) | OptSellTypeSellToClose optSellType = 1 + iota
constant OptSellTypeSellToOpen (line 1571) | OptSellTypeSellToOpen
function NewOptSellType (line 1622) | func NewOptSellType(s string) (optSellType, error) {
type relType (line 1631) | type relType
method Valid (line 1643) | func (e relType) Valid() bool {
method String (line 1649) | func (e relType) String() string {
method FromString (line 1656) | func (e *relType) FromString(in string) error {
method UnmarshalXML (line 1669) | func (e *relType) UnmarshalXML(d *xml.Decoder, start xml.StartElement)...
method MarshalXML (line 1679) | func (e relType) MarshalXML(enc *xml.Encoder, start xml.StartElement) ...
constant RelTypeSpread (line 1635) | RelTypeSpread relType = 1 + iota
constant RelTypeStraddle (line 1636) | RelTypeStraddle
constant RelTypeNone (line 1637) | RelTypeNone
constant RelTypeOther (line 1638) | RelTypeOther
function NewRelType (line 1689) | func NewRelType(s string) (relType, error) {
type charType (line 1698) | type charType
method Valid (line 1710) | func (e charType) Valid() bool {
method String (line 1716) | func (e charType) String() string {
method FromString (line 1723) | func (e *charType) FromString(in string) error {
method UnmarshalXML (line 1736) | func (e *charType) UnmarshalXML(d *xml.Decoder, start xml.StartElement...
method MarshalXML (line 1746) | func (e charType) MarshalXML(enc *xml.Encoder, start xml.StartElement)...
constant CharTypeAlphaOnly (line 1702) | CharTypeAlphaOnly charType = 1 + iota
constant CharTypeNumericOnly (line 1703) | CharTypeNumericOnly
constant CharTypeAlphaOrNumeric (line 1704) | CharTypeAlphaOrNumeric
constant CharTypeAlphaAndNumeric (line 1705) | CharTypeAlphaAndNumeric
function NewCharType (line 1756) | func NewCharType(s string) (charType, error) {
type syncMode (line 1765) | type syncMode
method Valid (line 1775) | func (e syncMode) Valid() bool {
method String (line 1781) | func (e syncMode) String() string {
method FromString (line 1788) | func (e *syncMode) FromString(in string) error {
method UnmarshalXML (line 1801) | func (e *syncMode) UnmarshalXML(d *xml.Decoder, start xml.StartElement...
method MarshalXML (line 1811) | func (e syncMode) MarshalXML(enc *xml.Encoder, start xml.StartElement)...
constant SyncModeFull (line 1769) | SyncModeFull syncMode = 1 + iota
constant SyncModeLite (line 1770) | SyncModeLite
function NewSyncMode (line 1821) | func NewSyncMode(s string) (syncMode, error) {
type ofxSec (line 1830) | type ofxSec
method Valid (line 1840) | func (e ofxSec) Valid() bool {
method String (line 1846) | func (e ofxSec) String() string {
method FromString (line 1853) | func (e *ofxSec) FromString(in string) error {
method UnmarshalXML (line 1866) | func (e *ofxSec) UnmarshalXML(d *xml.Decoder, start xml.StartElement) ...
method MarshalXML (line 1876) | func (e ofxSec) MarshalXML(enc *xml.Encoder, start xml.StartElement) e...
constant OfxSecNone (line 1834) | OfxSecNone ofxSec = 1 + iota
constant OfxSecType1 (line 1835) | OfxSecType1
function NewOfxSec (line 1886) | func NewOfxSec(s string) (ofxSec, error) {
type debtType (line 1895) | type debtType
method Valid (line 1905) | func (e debtType) Valid() bool {
method String (line 1911) | func (e debtType) String() string {
method FromString (line 1918) | func (e *debtType) FromString(in string) error {
method UnmarshalXML (line 1931) | func (e *debtType) UnmarshalXML(d *xml.Decoder, start xml.StartElement...
method MarshalXML (line 1941) | func (e debtType) MarshalXML(enc *xml.Encoder, start xml.StartElement)...
constant DebtTypeCoupon (line 1899) | DebtTypeCoupon debtType = 1 + iota
constant DebtTypeZero (line 1900) | DebtTypeZero
function NewDebtType (line 1951) | func NewDebtType(s string) (debtType, error) {
type debtClass (line 1960) | type debtClass
method Valid (line 1972) | func (e debtClass) Valid() bool {
method String (line 1978) | func (e debtClass) String() string {
method FromString (line 1985) | func (e *debtClass) FromString(in string) error {
method UnmarshalXML (line 1998) | func (e *debtClass) UnmarshalXML(d *xml.Decoder, start xml.StartElemen...
method MarshalXML (line 2008) | func (e debtClass) MarshalXML(enc *xml.Encoder, start xml.StartElement...
constant DebtClassTreasury (line 1964) | DebtClassTreasury debtClass = 1 + iota
constant DebtClassMunicipal (line 1965) | DebtClassMunicipal
constant DebtClassCorporate (line 1966) | DebtClassCorporate
constant DebtClassOther (line 1967) | DebtClassOther
function NewDebtClass (line 2018) | func NewDebtClass(s string) (debtClass, error) {
type couponFreq (line 2027) | type couponFreq
method Valid (line 2040) | func (e couponFreq) Valid() bool {
method String (line 2046) | func (e couponFreq) String() string {
method FromString (line 2053) | func (e *couponFreq) FromString(in string) error {
method UnmarshalXML (line 2066) | func (e *couponFreq) UnmarshalXML(d *xml.Decoder, start xml.StartEleme...
method MarshalXML (line 2076) | func (e couponFreq) MarshalXML(enc *xml.Encoder, start xml.StartElemen...
constant CouponFreqMonthly (line 2031) | CouponFreqMonthly couponFreq = 1 + iota
constant CouponFreqQuarterly (line 2032) | CouponFreqQuarterly
constant CouponFreqSemiannual (line 2033) | CouponFreqSemiannual
constant CouponFreqAnnual (line 2034) | CouponFreqAnnual
constant CouponFreqOther (line 2035) | CouponFreqOther
function NewCouponFreq (line 2086) | func NewCouponFreq(s string) (couponFreq, error) {
type callType (line 2095) | type callType
method Valid (line 2107) | func (e callType) Valid() bool {
method String (line 2113) | func (e callType) String() string {
method FromString (line 2120) | func (e *callType) FromString(in string) error {
method UnmarshalXML (line 2133) | func (e *callType) UnmarshalXML(d *xml.Decoder, start xml.StartElement...
method MarshalXML (line 2143) | func (e callType) MarshalXML(enc *xml.Encoder, start xml.StartElement)...
constant CallTypeCall (line 2099) | CallTypeCall callType = 1 + iota
constant CallTypePut (line 2100) | CallTypePut
constant CallTypePrefund (line 2101) | CallTypePrefund
constant CallTypeMaturity (line 2102) | CallTypeMaturity
function NewCallType (line 2153) | func NewCallType(s string) (callType, error) {
type assetClass (line 2162) | type assetClass
method Valid (line 2177) | func (e assetClass) Valid() bool {
method String (line 2183) | func (e assetClass) String() string {
method FromString (line 2190) | func (e *assetClass) FromString(in string) error {
method UnmarshalXML (line 2203) | func (e *assetClass) UnmarshalXML(d *xml.Decoder, start xml.StartEleme...
method MarshalXML (line 2213) | func (e assetClass) MarshalXML(enc *xml.Encoder, start xml.StartElemen...
constant AssetClassDomesticBond (line 2166) | AssetClassDomesticBond assetClass = 1 + iota
constant AssetClassIntlBond (line 2167) | AssetClassIntlBond
constant AssetClassLargeStock (line 2168) | AssetClassLargeStock
constant AssetClassSmallStock (line 2169) | AssetClassSmallStock
constant AssetClassIntlStock (line 2170) | AssetClassIntlStock
constant AssetClassMoneyMrkt (line 2171) | AssetClassMoneyMrkt
constant AssetClassOther (line 2172) | AssetClassOther
function NewAssetClass (line 2223) | func NewAssetClass(s string) (assetClass, error) {
type mfType (line 2232) | type mfType
method Valid (line 2243) | func (e mfType) Valid() bool {
method String (line 2249) | func (e mfType) String() string {
method FromString (line 2256) | func (e *mfType) FromString(in string) error {
method UnmarshalXML (line 2269) | func (e *mfType) UnmarshalXML(d *xml.Decoder, start xml.StartElement) ...
method MarshalXML (line 2279) | func (e mfType) MarshalXML(enc *xml.Encoder, start xml.StartElement) e...
constant MfTypeOpenEnd (line 2236) | MfTypeOpenEnd mfType = 1 + iota
constant MfTypeCloseEnd (line 2237) | MfTypeCloseEnd
constant MfTypeOther (line 2238) | MfTypeOther
function NewMfType (line 2289) | func NewMfType(s string) (mfType, error) {
type optType (line 2298) | type optType
method Valid (line 2308) | func (e optType) Valid() bool {
method String (line 2314) | func (e optType) String() string {
method FromString (line 2321) | func (e *optType) FromString(in string) error {
method UnmarshalXML (line 2334) | func (e *optType) UnmarshalXML(d *xml.Decoder, start xml.StartElement)...
method MarshalXML (line 2344) | func (e optType) MarshalXML(enc *xml.Encoder, start xml.StartElement) ...
constant OptTypePut (line 2302) | OptTypePut optType = 1 + iota
constant OptTypeCall (line 2303) | OptTypeCall
function NewOptType (line 2354) | func NewOptType(s string) (optType, error) {
type stockType (line 2363) | type stockType
method Valid (line 2375) | func (e stockType) Valid() bool {
method String (line 2381) | func (e stockType) String() string {
method FromString (line 2388) | func (e *stockType) FromString(in string) error {
method UnmarshalXML (line 2401) | func (e *stockType) UnmarshalXML(d *xml.Decoder, start xml.StartElemen...
method MarshalXML (line 2411) | func (e stockType) MarshalXML(enc *xml.Encoder, start xml.StartElement...
constant StockTypeCommon (line 2367) | StockTypeCommon stockType = 1 + iota
constant StockTypePreferred (line 2368) | StockTypePreferred
constant StockTypeConvertible (line 2369) | StockTypeConvertible
constant StockTypeOther (line 2370) | StockTypeOther
function NewStockType (line 2421) | func NewStockType(s string) (stockType, error) {
type holderType (line 2430) | type holderType
method Valid (line 2443) | func (e holderType) Valid() bool {
method String (line 2449) | func (e holderType) String() string {
method FromString (line 2456) | func (e *holderType) FromString(in string) error {
method UnmarshalXML (line 2469) | func (e *holderType) UnmarshalXML(d *xml.Decoder, start xml.StartEleme...
method MarshalXML (line 2479) | func (e holderType) MarshalXML(enc *xml.Encoder, start xml.StartElemen...
constant HolderTypeIndividual (line 2434) | HolderTypeIndividual holderType = 1 + iota
constant HolderTypeJoint (line 2435) | HolderTypeJoint
constant HolderTypeCustodial (line 2436) | HolderTypeCustodial
constant HolderTypeTrust (line 2437) | HolderTypeTrust
constant HolderTypeOther (line 2438) | HolderTypeOther
function NewHolderType (line 2489) | func NewHolderType(s string) (holderType, error) {
type acctClassification (line 2498) | type acctClassification
method Valid (line 2510) | func (e acctClassification) Valid() bool {
method String (line 2516) | func (e acctClassification) String() string {
method FromString (line 2523) | func (e *acctClassification) FromString(in string) error {
method UnmarshalXML (line 2536) | func (e *acctClassification) UnmarshalXML(d *xml.Decoder, start xml.St...
method MarshalXML (line 2546) | func (e acctClassification) MarshalXML(enc *xml.Encoder, start xml.Sta...
constant AcctClassificationPersonal (line 2502) | AcctClassificationPersonal acctClassification = 1 + iota
constant AcctClassificationBusiness (line 2503) | AcctClassificationBusiness
constant AcctClassificationCorporate (line 2504) | AcctClassificationCorporate
constant AcctClassificationOther (line 2505) | AcctClassificationOther
function NewAcctClassification (line 2556) | func NewAcctClassification(s string) (acctClassification, error) {
type svcStatus (line 2565) | type svcStatus
method Valid (line 2576) | func (e svcStatus) Valid() bool {
method String (line 2582) | func (e svcStatus) String() string {
method FromString (line 2589) | func (e *svcStatus) FromString(in string) error {
method UnmarshalXML (line 2602) | func (e *svcStatus) UnmarshalXML(d *xml.Decoder, start xml.StartElemen...
method MarshalXML (line 2612) | func (e svcStatus) MarshalXML(enc *xml.Encoder, start xml.StartElement...
constant SvcStatusAvail (line 2569) | SvcStatusAvail svcStatus = 1 + iota
constant SvcStatusPend (line 2570) | SvcStatusPend
constant SvcStatusActive (line 2571) | SvcStatusActive
function NewSvcStatus (line 2622) | func NewSvcStatus(s string) (svcStatus, error) {
type usProductType (line 2631) | type usProductType
method Valid (line 2650) | func (e usProductType) Valid() bool {
method String (line 2656) | func (e usProductType) String() string {
method FromString (line 2663) | func (e *usProductType) FromString(in string) error {
method UnmarshalXML (line 2676) | func (e *usProductType) UnmarshalXML(d *xml.Decoder, start xml.StartEl...
method MarshalXML (line 2686) | func (e usProductType) MarshalXML(enc *xml.Encoder, start xml.StartEle...
constant UsProductType401K (line 2635) | UsProductType401K usProductType = 1 + iota
constant UsProductType403B (line 2636) | UsProductType403B
constant UsProductTypeIRA (line 2637) | UsProductTypeIRA
constant UsProductTypeKEOGH (line 2638) | UsProductTypeKEOGH
constant UsProductTypeOther (line 2639) | UsProductTypeOther
constant UsProductTypeSARSEP (line 2640) | UsProductTypeSARSEP
constant UsProductTypeSimple (line 2641) | UsProductTypeSimple
constant UsProductTypeNormal (line 2642) | UsProductTypeNormal
constant UsProductTypeTDA (line 2643) | UsProductTypeTDA
constant UsProductTypeTrust (line 2644) | UsProductTypeTrust
constant UsProductTypeUGMA (line 2645) | UsProductTypeUGMA
function NewUsProductType (line 2696) | func NewUsProductType(s string) (usProductType, error) {
FILE: constants_test.go
function TestOfxVersion (line 16) | func TestOfxVersion(t *testing.T) {
function TestAcctType (line 73) | func TestAcctType(t *testing.T) {
function TestTrnType (line 130) | func TestTrnType(t *testing.T) {
function TestImageType (line 187) | func TestImageType(t *testing.T) {
function TestImageRefType (line 244) | func TestImageRefType(t *testing.T) {
function TestCheckSup (line 301) | func TestCheckSup(t *testing.T) {
function TestCorrectAction (line 358) | func TestCorrectAction(t *testing.T) {
function TestBalType (line 415) | func TestBalType(t *testing.T) {
function TestInv401kSource (line 472) | func TestInv401kSource(t *testing.T) {
function TestSubAcctType (line 529) | func TestSubAcctType(t *testing.T) {
function TestBuyType (line 586) | func TestBuyType(t *testing.T) {
function TestOptAction (line 643) | func TestOptAction(t *testing.T) {
function TestTferAction (line 700) | func TestTferAction(t *testing.T) {
function TestPosType (line 757) | func TestPosType(t *testing.T) {
function TestSecured (line 814) | func TestSecured(t *testing.T) {
function TestDuration (line 871) | func TestDuration(t *testing.T) {
function TestRestriction (line 928) | func TestRestriction(t *testing.T) {
function TestUnitType (line 985) | func TestUnitType(t *testing.T) {
function TestOptBuyType (line 1042) | func TestOptBuyType(t *testing.T) {
function TestSellType (line 1099) | func TestSellType(t *testing.T) {
function TestLoanPmtFreq (line 1156) | func TestLoanPmtFreq(t *testing.T) {
function TestIncomeType (line 1213) | func TestIncomeType(t *testing.T) {
function TestSellReason (line 1270) | func TestSellReason(t *testing.T) {
function TestOptSellType (line 1327) | func TestOptSellType(t *testing.T) {
function TestRelType (line 1384) | func TestRelType(t *testing.T) {
function TestCharType (line 1441) | func TestCharType(t *testing.T) {
function TestSyncMode (line 1498) | func TestSyncMode(t *testing.T) {
function TestOfxSec (line 1555) | func TestOfxSec(t *testing.T) {
function TestDebtType (line 1612) | func TestDebtType(t *testing.T) {
function TestDebtClass (line 1669) | func TestDebtClass(t *testing.T) {
function TestCouponFreq (line 1726) | func TestCouponFreq(t *testing.T) {
function TestCallType (line 1783) | func TestCallType(t *testing.T) {
function TestAssetClass (line 1840) | func TestAssetClass(t *testing.T) {
function TestMfType (line 1897) | func TestMfType(t *testing.T) {
function TestOptType (line 1954) | func TestOptType(t *testing.T) {
function TestStockType (line 2011) | func TestStockType(t *testing.T) {
function TestHolderType (line 2068) | func TestHolderType(t *testing.T) {
function TestAcctClassification (line 2125) | func TestAcctClassification(t *testing.T) {
function TestSvcStatus (line 2182) | func TestSvcStatus(t *testing.T) {
function TestUsProductType (line 2239) | func TestUsProductType(t *testing.T) {
FILE: creditcard.go
type CCStatementRequest (line 10) | type CCStatementRequest struct
method Name (line 25) | func (r *CCStatementRequest) Name() string {
method Valid (line 31) | func (r *CCStatementRequest) Valid(version ofxVersion) (bool, error) {
method Type (line 41) | func (r *CCStatementRequest) Type() messageType {
type CCStatementResponse (line 48) | type CCStatementResponse struct
method Name (line 74) | func (sr *CCStatementResponse) Name() string {
method Valid (line 79) | func (sr *CCStatementResponse) Valid(version ofxVersion) (bool, error) {
method Type (line 89) | func (sr *CCStatementResponse) Type() messageType {
FILE: creditcard_test.go
function TestMarshalCCStatementRequest (line 9) | func TestMarshalCCStatementRequest(t *testing.T) {
function TestUnmarshalCCStatementResponse102 (line 72) | func TestUnmarshalCCStatementResponse102(t *testing.T) {
FILE: discovercard_client.go
type DiscoverCardClient (line 18) | type DiscoverCardClient struct
method RawRequest (line 82) | func (c *DiscoverCardClient) RawRequest(URL string, r io.Reader) (*htt...
method RequestNoParse (line 101) | func (c *DiscoverCardClient) RequestNoParse(r *Request) (*http.Respons...
method Request (line 107) | func (c *DiscoverCardClient) Request(r *Request) (*Response, error) {
function NewDiscoverCardClient (line 24) | func NewDiscoverCardClient(bc *BasicClient) Client {
function discoverCardHTTPPost (line 28) | func discoverCardHTTPPost(URL string, r io.Reader) (*http.Response, erro...
FILE: invstmt.go
type InvStatementRequest (line 11) | type InvStatementRequest struct
method Name (line 31) | func (r *InvStatementRequest) Name() string {
method Valid (line 37) | func (r *InvStatementRequest) Valid(version ofxVersion) (bool, error) {
method Type (line 47) | func (r *InvStatementRequest) Type() messageType {
type InvTran (line 54) | type InvTran struct
type InvBuy (line 66) | type InvBuy struct
type InvSell (line 95) | type InvSell struct
type BuyDebt (line 123) | type BuyDebt struct
method TransactionType (line 130) | func (t BuyDebt) TransactionType() string {
method InvTransaction (line 134) | func (t BuyDebt) InvTransaction() InvTran {
type BuyMF (line 139) | type BuyMF struct
method TransactionType (line 147) | func (t BuyMF) TransactionType() string {
method InvTransaction (line 151) | func (t BuyMF) InvTransaction() InvTran {
type BuyOpt (line 156) | type BuyOpt struct
method TransactionType (line 164) | func (t BuyOpt) TransactionType() string {
method InvTransaction (line 168) | func (t BuyOpt) InvTransaction() InvTran {
type BuyOther (line 174) | type BuyOther struct
method TransactionType (line 180) | func (t BuyOther) TransactionType() string {
method InvTransaction (line 184) | func (t BuyOther) InvTransaction() InvTran {
type BuyStock (line 189) | type BuyStock struct
method TransactionType (line 196) | func (t BuyStock) TransactionType() string {
method InvTransaction (line 200) | func (t BuyStock) InvTransaction() InvTran {
type ClosureOpt (line 205) | type ClosureOpt struct
method TransactionType (line 218) | func (t ClosureOpt) TransactionType() string {
method InvTransaction (line 222) | func (t ClosureOpt) InvTransaction() InvTran {
type Income (line 228) | type Income struct
method TransactionType (line 244) | func (t Income) TransactionType() string {
method InvTransaction (line 248) | func (t Income) InvTransaction() InvTran {
type InvExpense (line 254) | type InvExpense struct
method TransactionType (line 267) | func (t InvExpense) TransactionType() string {
method InvTransaction (line 271) | func (t InvExpense) InvTransaction() InvTran {
type JrnlFund (line 277) | type JrnlFund struct
method TransactionType (line 286) | func (t JrnlFund) TransactionType() string {
method InvTransaction (line 290) | func (t JrnlFund) InvTransaction() InvTran {
type JrnlSec (line 296) | type JrnlSec struct
method TransactionType (line 306) | func (t JrnlSec) TransactionType() string {
method InvTransaction (line 310) | func (t JrnlSec) InvTransaction() InvTran {
type MarginInterest (line 315) | type MarginInterest struct
method TransactionType (line 325) | func (t MarginInterest) TransactionType() string {
method InvTransaction (line 329) | func (t MarginInterest) InvTransaction() InvTran {
type Reinvest (line 336) | type Reinvest struct
method TransactionType (line 356) | func (t Reinvest) TransactionType() string {
method InvTransaction (line 360) | func (t Reinvest) InvTransaction() InvTran {
type RetOfCap (line 366) | type RetOfCap struct
method TransactionType (line 379) | func (t RetOfCap) TransactionType() string {
method InvTransaction (line 383) | func (t RetOfCap) InvTransaction() InvTran {
type SellDebt (line 389) | type SellDebt struct
method TransactionType (line 397) | func (t SellDebt) TransactionType() string {
method InvTransaction (line 401) | func (t SellDebt) InvTransaction() InvTran {
type SellMF (line 406) | type SellMF struct
method TransactionType (line 415) | func (t SellMF) TransactionType() string {
method InvTransaction (line 419) | func (t SellMF) InvTransaction() InvTran {
type SellOpt (line 426) | type SellOpt struct
method TransactionType (line 437) | func (t SellOpt) TransactionType() string {
method InvTransaction (line 441) | func (t SellOpt) InvTransaction() InvTran {
type SellOther (line 447) | type SellOther struct
method TransactionType (line 453) | func (t SellOther) TransactionType() string {
method InvTransaction (line 457) | func (t SellOther) InvTransaction() InvTran {
type SellStock (line 462) | type SellStock struct
method TransactionType (line 469) | func (t SellStock) TransactionType() string {
method InvTransaction (line 473) | func (t SellStock) InvTransaction() InvTran {
type Split (line 478) | type Split struct
method TransactionType (line 495) | func (t Split) TransactionType() string {
method InvTransaction (line 499) | func (t Split) InvTransaction() InvTran {
type Transfer (line 504) | type Transfer struct
method TransactionType (line 520) | func (t Transfer) TransactionType() string {
method InvTransaction (line 524) | func (t Transfer) InvTransaction() InvTran {
type InvTransaction (line 530) | type InvTransaction interface
type InvBankTransaction (line 538) | type InvBankTransaction struct
type InvTranList (line 548) | type InvTranList struct
method UnmarshalXML (line 558) | func (l *InvTranList) UnmarshalXML(d *xml.Decoder, start xml.StartElem...
method MarshalXML (line 716) | func (l *InvTranList) MarshalXML(e *xml.Encoder, start xml.StartElemen...
type InvPosition (line 830) | type InvPosition struct
type Position (line 846) | type Position interface
type DebtPosition (line 852) | type DebtPosition struct
method PositionType (line 858) | func (p DebtPosition) PositionType() string {
method InvPosition (line 863) | func (p DebtPosition) InvPosition() InvPosition {
type MFPosition (line 868) | type MFPosition struct
method PositionType (line 878) | func (p MFPosition) PositionType() string {
method InvPosition (line 883) | func (p MFPosition) InvPosition() InvPosition {
type OptPosition (line 888) | type OptPosition struct
method PositionType (line 895) | func (p OptPosition) PositionType() string {
method InvPosition (line 900) | func (p OptPosition) InvPosition() InvPosition {
type OtherPosition (line 906) | type OtherPosition struct
method PositionType (line 912) | func (p OtherPosition) PositionType() string {
method InvPosition (line 917) | func (p OtherPosition) InvPosition() InvPosition {
type StockPosition (line 922) | type StockPosition struct
method PositionType (line 931) | func (p StockPosition) PositionType() string {
method InvPosition (line 936) | func (p StockPosition) InvPosition() InvPosition {
type PositionList (line 942) | type PositionList
method UnmarshalXML (line 945) | func (p *PositionList) UnmarshalXML(d *xml.Decoder, start xml.StartEle...
method MarshalXML (line 995) | func (p PositionList) MarshalXML(e *xml.Encoder, start xml.StartElemen...
type InvBalance (line 1036) | type InvBalance struct
type OO (line 1047) | type OO struct
type OpenOrder (line 1066) | type OpenOrder interface
type OOBuyDebt (line 1071) | type OOBuyDebt struct
method OrderType (line 1079) | func (o OOBuyDebt) OrderType() string {
type OOBuyMF (line 1084) | type OOBuyMF struct
method OrderType (line 1092) | func (o OOBuyMF) OrderType() string {
type OOBuyOpt (line 1097) | type OOBuyOpt struct
method OrderType (line 1104) | func (o OOBuyOpt) OrderType() string {
type OOBuyOther (line 1110) | type OOBuyOther struct
method OrderType (line 1117) | func (o OOBuyOther) OrderType() string {
type OOBuyStock (line 1122) | type OOBuyStock struct
method OrderType (line 1129) | func (o OOBuyStock) OrderType() string {
type OOSellDebt (line 1134) | type OOSellDebt struct
method OrderType (line 1140) | func (o OOSellDebt) OrderType() string {
type OOSellMF (line 1145) | type OOSellMF struct
method OrderType (line 1154) | func (o OOSellMF) OrderType() string {
type OOSellOpt (line 1159) | type OOSellOpt struct
method OrderType (line 1166) | func (o OOSellOpt) OrderType() string {
type OOSellOther (line 1172) | type OOSellOther struct
method OrderType (line 1179) | func (o OOSellOther) OrderType() string {
type OOSellStock (line 1184) | type OOSellStock struct
method OrderType (line 1191) | func (o OOSellStock) OrderType() string {
type OOSwitchMF (line 1197) | type OOSwitchMF struct
method OrderType (line 1206) | func (o OOSwitchMF) OrderType() string {
type OOList (line 1211) | type OOList
method UnmarshalXML (line 1214) | func (o *OOList) UnmarshalXML(d *xml.Decoder, start xml.StartElement) ...
method MarshalXML (line 1300) | func (o OOList) MarshalXML(e *xml.Encoder, start xml.StartElement) err...
type ContribSecurity (line 1364) | type ContribSecurity struct
type VestInfo (line 1385) | type VestInfo struct
type LoanInfo (line 1392) | type LoanInfo struct
type Inv401KSummaryAggregate (line 1414) | type Inv401KSummaryAggregate struct
type Inv401KSummaryPeriod (line 1428) | type Inv401KSummaryPeriod struct
type Inv401K (line 1439) | type Inv401K struct
type Inv401KBal (line 1467) | type Inv401KBal struct
type InvStatementResponse (line 1485) | type InvStatementResponse struct
method Name (line 1504) | func (sr *InvStatementResponse) Name() string {
method Valid (line 1509) | func (sr *InvStatementResponse) Valid(version ofxVersion) (bool, error) {
method Type (line 1519) | func (sr *InvStatementResponse) Type() messageType {
FILE: invstmt_test.go
function TestMarshalInvStatementRequest (line 12) | func TestMarshalInvStatementRequest(t *testing.T) {
function TestUnmarshalInvStatementResponse (line 87) | func TestUnmarshalInvStatementResponse(t *testing.T) {
function TestUnmarshalInvStatementResponse102 (line 608) | func TestUnmarshalInvStatementResponse102(t *testing.T) {
function TestUnmarshalInvTranList (line 964) | func TestUnmarshalInvTranList(t *testing.T) {
function TestUnmarshalPositionList (line 1324) | func TestUnmarshalPositionList(t *testing.T) {
function TestUnmarshalOOList (line 1497) | func TestUnmarshalOOList(t *testing.T) {
function TestSecurityInfo (line 1871) | func TestSecurityInfo(t *testing.T) {
function TestInvPosition (line 1893) | func TestInvPosition(t *testing.T) {
function TestInvTransaction (line 1915) | func TestInvTransaction(t *testing.T) {
FILE: profile.go
type ProfileRequest (line 12) | type ProfileRequest struct
method Name (line 23) | func (r *ProfileRequest) Name() string {
method Valid (line 29) | func (r *ProfileRequest) Valid(version ofxVersion) (bool, error) {
method Type (line 40) | func (r *ProfileRequest) Type() messageType {
type SignonInfo (line 48) | type SignonInfo struct
type MessageSet (line 72) | type MessageSet struct
type MessageSetList (line 90) | type MessageSetList
method UnmarshalXML (line 93) | func (msl *MessageSetList) UnmarshalXML(d *xml.Decoder, start xml.Star...
method MarshalXML (line 131) | func (msl *MessageSetList) MarshalXML(e *xml.Encoder, start xml.StartE...
type ProfileResponse (line 164) | type ProfileResponse struct
method Name (line 189) | func (pr *ProfileResponse) Name() string {
method Valid (line 194) | func (pr *ProfileResponse) Valid(version ofxVersion) (bool, error) {
method Type (line 204) | func (pr *ProfileResponse) Type() messageType {
FILE: profile_test.go
function TestMarshalProfileRequest (line 9) | func TestMarshalProfileRequest(t *testing.T) {
function TestUnmarshalProfileResponse102 (line 65) | func TestUnmarshalProfileResponse102(t *testing.T) {
FILE: request.go
type Request (line 15) | type Request struct
method SetClientFields (line 66) | func (oq *Request) SetClientFields(c Client) {
method Marshal (line 80) | func (oq *Request) Marshal() (*bytes.Buffer, error) {
function encodeMessageSet (line 38) | func encodeMessageSet(e *xml.Encoder, requests []Message, set messageTyp...
FILE: request_test.go
function marshalCheckRequest (line 12) | func marshalCheckRequest(t *testing.T, request *Request, expected string) {
FILE: response.go
type Response (line 19) | type Response struct
method readSGMLHeaders (line 38) | func (or *Response) readSGMLHeaders(r *bufio.Reader) error {
method readXMLHeaders (line 111) | func (or *Response) readXMLHeaders(decoder *xml.Decoder) error {
method Valid (line 380) | func (or *Response) Valid() (bool, error) {
method Marshal (line 414) | func (or *Response) Marshal() (*bytes.Buffer, error) {
constant guessVersionCheckBytes (line 184) | guessVersionCheckBytes = 1024
function guessVersion (line 189) | func guessVersion(r *bufio.Reader) (bool, error) {
function decodeMessageSet (line 233) | func decodeMessageSet(d *xml.Decoder, start xml.StartElement, msgs *[]Me...
function ParseResponse (line 273) | func ParseResponse(reader io.Reader) (*Response, error) {
function DecodeResponse (line 284) | func DecodeResponse(reader io.Reader) (*Response, error) {
type errInvalid (line 480) | type errInvalid
method Error (line 482) | func (e errInvalid) Error() string {
method AddErr (line 490) | func (e *errInvalid) AddErr(err error) {
method ErrOrNil (line 500) | func (e errInvalid) ErrOrNil() error {
FILE: response_test.go
function equalMethodOf (line 19) | func equalMethodOf(v reflect.Value) reflect.Value {
function valueToString (line 37) | func valueToString(v reflect.Value) string {
function checkEqual (line 55) | func checkEqual(t *testing.T, fieldName string, expected, actual reflect...
function checkResponsesEqual (line 137) | func checkResponsesEqual(t *testing.T, expected, actual *Response) {
function checkResponseRoundTrip (line 141) | func checkResponseRoundTrip(t *testing.T, response *Response) {
function TestValidSamples (line 155) | func TestValidSamples(t *testing.T) {
function TestInvalidResponse (line 177) | func TestInvalidResponse(t *testing.T) {
function TestErrInvalidError (line 263) | func TestErrInvalidError(t *testing.T) {
function TestErrInvalidAddErr (line 275) | func TestErrInvalidAddErr(t *testing.T) {
function TestErrInvalidErrOrNil (line 305) | func TestErrInvalidErrOrNil(t *testing.T) {
FILE: seclist.go
type SecurityID (line 10) | type SecurityID struct
type SecurityRequest (line 19) | type SecurityRequest struct
type SecListRequest (line 29) | type SecListRequest struct
method Name (line 39) | func (r *SecListRequest) Name() string {
method Valid (line 45) | func (r *SecListRequest) Valid(version ofxVersion) (bool, error) {
method Type (line 55) | func (r *SecListRequest) Type() messageType {
type SecListResponse (line 64) | type SecListResponse struct
method Name (line 74) | func (r *SecListResponse) Name() string {
method Valid (line 79) | func (r *SecListResponse) Valid(version ofxVersion) (bool, error) {
method Type (line 89) | func (r *SecListResponse) Type() messageType {
type Security (line 95) | type Security interface
type SecInfo (line 102) | type SecInfo struct
type DebtInfo (line 116) | type DebtInfo struct
method SecurityType (line 136) | func (i DebtInfo) SecurityType() string {
method SecurityInfo (line 141) | func (i DebtInfo) SecurityInfo() SecInfo {
type AssetPortion (line 147) | type AssetPortion struct
type FiAssetPortion (line 156) | type FiAssetPortion struct
type MFInfo (line 163) | type MFInfo struct
method SecurityType (line 174) | func (i MFInfo) SecurityType() string {
method SecurityInfo (line 179) | func (i MFInfo) SecurityInfo() SecInfo {
type OptInfo (line 184) | type OptInfo struct
method SecurityType (line 197) | func (i OptInfo) SecurityType() string {
method SecurityInfo (line 202) | func (i OptInfo) SecurityInfo() SecInfo {
type OtherInfo (line 208) | type OtherInfo struct
method SecurityType (line 217) | func (i OtherInfo) SecurityType() string {
method SecurityInfo (line 222) | func (i OtherInfo) SecurityInfo() SecInfo {
type StockInfo (line 227) | type StockInfo struct
method SecurityType (line 238) | func (i StockInfo) SecurityType() string {
method SecurityInfo (line 243) | func (i StockInfo) SecurityInfo() SecInfo {
type SecurityList (line 249) | type SecurityList struct
method Name (line 255) | func (r *SecurityList) Name() string {
method Valid (line 260) | func (r *SecurityList) Valid(version ofxVersion) (bool, error) {
method Type (line 267) | func (r *SecurityList) Type() messageType {
method UnmarshalXML (line 272) | func (r *SecurityList) UnmarshalXML(d *xml.Decoder, start xml.StartEle...
method MarshalXML (line 322) | func (r *SecurityList) MarshalXML(e *xml.Encoder, start xml.StartEleme...
FILE: signon.go
type SignonRequest (line 11) | type SignonRequest struct
method Name (line 27) | func (r *SignonRequest) Name() string {
method Valid (line 33) | func (r *SignonRequest) Valid(version ofxVersion) (bool, error) {
type SignonResponse (line 62) | type SignonResponse struct
method Name (line 78) | func (r *SignonResponse) Name() string {
method Valid (line 83) | func (r *SignonResponse) Valid(version ofxVersion) (bool, error) {
FILE: signon_test.go
function TestMarshalInvalidSignons (line 7) | func TestMarshalInvalidSignons(t *testing.T) {
FILE: signup.go
type AcctInfoRequest (line 10) | type AcctInfoRequest struct
method Name (line 20) | func (r *AcctInfoRequest) Name() string {
method Valid (line 26) | func (r *AcctInfoRequest) Valid(version ofxVersion) (bool, error) {
method Type (line 36) | func (r *AcctInfoRequest) Type() messageType {
type HolderInfo (line 41) | type HolderInfo struct
type BankAcctInfo (line 62) | type BankAcctInfo struct
method String (line 77) | func (bai *BankAcctInfo) String() string {
type CCAcctInfo (line 84) | type CCAcctInfo struct
method String (line 95) | func (ci *CCAcctInfo) String() string {
type InvAcctInfo (line 102) | type InvAcctInfo struct
method String (line 113) | func (iai *InvAcctInfo) String() string {
type AcctInfo (line 120) | type AcctInfo struct
type AcctInfoResponse (line 138) | type AcctInfoResponse struct
method Name (line 149) | func (air *AcctInfoResponse) Name() string {
method Valid (line 154) | func (air *AcctInfoResponse) Valid(version ofxVersion) (bool, error) {
method Type (line 164) | func (air *AcctInfoResponse) Type() messageType {
FILE: signup_test.go
function TestMarshalAcctInfoRequest (line 9) | func TestMarshalAcctInfoRequest(t *testing.T) {
function TestUnmarshalAcctInfoResponse (line 64) | func TestUnmarshalAcctInfoResponse(t *testing.T) {
FILE: types.go
type Int (line 17) | type Int
method UnmarshalXML (line 21) | func (i *Int) UnmarshalXML(d *xml.Decoder, start xml.StartElement) err...
method Equal (line 41) | func (i Int) Equal(o Int) bool {
type Amount (line 47) | type Amount struct
method UnmarshalXML (line 53) | func (a *Amount) UnmarshalXML(d *xml.Decoder, start xml.StartElement) ...
method String (line 74) | func (a Amount) String() string {
method MarshalXML (line 79) | func (a Amount) MarshalXML(e *xml.Encoder, start xml.StartElement) err...
method Equal (line 84) | func (a Amount) Equal(o Amount) bool {
type Date (line 89) | type Date struct
method UnmarshalXML (line 106) | func (od *Date) UnmarshalXML(d *xml.Decoder, start xml.StartElement) e...
method String (line 169) | func (od Date) String() string {
method MarshalXML (line 191) | func (od Date) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
method Equal (line 197) | func (od Date) Equal(o Date) bool {
function NewDate (line 202) | func NewDate(year int, month time.Month, day, hour, min, sec, nsec int, ...
function NewDateGMT (line 210) | func NewDateGMT(year int, month time.Month, day, hour, min, sec, nsec in...
type String (line 215) | type String
method UnmarshalXML (line 219) | func (os *String) UnmarshalXML(d *xml.Decoder, start xml.StartElement)...
method String (line 230) | func (os *String) String() string {
method Equal (line 235) | func (os String) Equal(o String) bool {
type Boolean (line 240) | type Boolean
method UnmarshalXML (line 244) | func (ob *Boolean) UnmarshalXML(d *xml.Decoder, start xml.StartElement...
method MarshalXML (line 263) | func (ob Boolean) MarshalXML(e *xml.Encoder, start xml.StartElement) e...
method String (line 271) | func (ob *Boolean) String() string {
method Equal (line 276) | func (ob Boolean) Equal(o Boolean) bool {
type UID (line 281) | type UID
method UnmarshalXML (line 285) | func (ou *UID) UnmarshalXML(d *xml.Decoder, start xml.StartElement) er...
method RecommendedFormat (line 297) | func (ou UID) RecommendedFormat() (bool, error) {
method Valid (line 309) | func (ou UID) Valid() (bool, error) {
method Equal (line 317) | func (ou UID) Equal(o UID) bool {
function RandomUID (line 322) | func RandomUID() (*UID, error) {
type CurrSymbol (line 336) | type CurrSymbol struct
method UnmarshalXML (line 342) | func (c *CurrSymbol) UnmarshalXML(d *xml.Decoder, start xml.StartEleme...
method MarshalXML (line 361) | func (c CurrSymbol) MarshalXML(e *xml.Encoder, start xml.StartElement)...
method Equal (line 366) | func (c CurrSymbol) Equal(o CurrSymbol) bool {
method Valid (line 371) | func (c CurrSymbol) Valid() (bool, error) {
function NewCurrSymbol (line 380) | func NewCurrSymbol(s string) (*CurrSymbol, error) {
FILE: types_test.go
function getTypeName (line 11) | func getTypeName(i interface{}) string {
function marshalHelper (line 24) | func marshalHelper(t *testing.T, expected string, i interface{}) {
function unmarshalHelper2 (line 37) | func unmarshalHelper2(t *testing.T, input string, expected interface{}, ...
function unmarshalHelper (line 50) | func unmarshalHelper(t *testing.T, input string, expected interface{}, o...
function TestMarshalInt (line 58) | func TestMarshalInt(t *testing.T) {
function TestUnmarshalInt (line 67) | func TestUnmarshalInt(t *testing.T) {
function TestMarshalAmount (line 79) | func TestMarshalAmount(t *testing.T) {
function TestUnmarshalAmount (line 103) | func TestUnmarshalAmount(t *testing.T) {
function TestAmountEqual (line 135) | func TestAmountEqual(t *testing.T) {
function TestMarshalDate (line 162) | func TestMarshalDate(t *testing.T) {
function TestUnmarshalDate (line 204) | func TestUnmarshalDate(t *testing.T) {
function TestDateEqual (line 275) | func TestDateEqual(t *testing.T) {
function TestMarshalString (line 306) | func TestMarshalString(t *testing.T) {
function TestUnmarshalString (line 317) | func TestUnmarshalString(t *testing.T) {
function TestStringString (line 333) | func TestStringString(t *testing.T) {
function TestMarshalBoolean (line 340) | func TestMarshalBoolean(t *testing.T) {
function TestUnmarshalBoolean (line 353) | func TestUnmarshalBoolean(t *testing.T) {
function TestStringBoolean (line 363) | func TestStringBoolean(t *testing.T) {
function TestMarshalUID (line 374) | func TestMarshalUID(t *testing.T) {
function TestUnmarshalUID (line 379) | func TestUnmarshalUID(t *testing.T) {
function TestUIDRecommendedFormat (line 388) | func TestUIDRecommendedFormat(t *testing.T) {
function TestUIDValid (line 407) | func TestUIDValid(t *testing.T) {
function TestRandomUID (line 422) | func TestRandomUID(t *testing.T) {
function TestMarshalCurrSymbol (line 432) | func TestMarshalCurrSymbol(t *testing.T) {
function TestUnmarshalCurrSymbol (line 443) | func TestUnmarshalCurrSymbol(t *testing.T) {
function TestCurrSymbolEqual (line 453) | func TestCurrSymbolEqual(t *testing.T) {
function TestCurrSymbolValid (line 465) | func TestCurrSymbolValid(t *testing.T) {
function TestNewCurrSymbol (line 485) | func TestNewCurrSymbol(t *testing.T) {
FILE: util.go
function nextNonWhitespaceToken (line 11) | func nextNonWhitespaceToken(decoder *xml.Decoder) (xml.Token, error) {
FILE: vanguard_client.go
type VanguardClient (line 15) | type VanguardClient struct
method RawRequest (line 53) | func (c *VanguardClient) RawRequest(URL string, r io.Reader) (*http.Re...
method RequestNoParse (line 111) | func (c *VanguardClient) RequestNoParse(r *Request) (*http.Response, e...
method Request (line 140) | func (c *VanguardClient) Request(r *Request) (*Response, error) {
function NewVanguardClient (line 21) | func NewVanguardClient(bc *BasicClient) Client {
function vanguardHttpClient (line 27) | func vanguardHttpClient() *http.Client {
function rawRequestCookiesInsecureCiphers (line 82) | func rawRequestCookiesInsecureCiphers(URL string, r io.Reader, cookies [...
Condensed preview — 57 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (639K chars).
[
{
"path": ".github/workflows/test.yml",
"chars": 1045,
"preview": "name: ofxgo CI Test\n\non: [push, pull_request]\n\njobs:\n test:\n strategy:\n matrix:\n go-version: [1.19.x, 1."
},
{
"path": "LICENSE",
"chars": 15220,
"preview": " GNU GENERAL PUBLIC LICENSE\n Version 2, June 1991\n\n Copyright (C) 1989, 1991 Fr"
},
{
"path": "README.md",
"chars": 5281,
"preview": "# OFXGo\n\n[](https://goreportcard.com/report/g"
},
{
"path": "bank.go",
"chars": 16419,
"preview": "package ofxgo\n\nimport (\n\t\"errors\"\n\t\"github.com/aclindsa/xml\"\n)\n\n// StatementRequest represents a request for a bank stat"
},
{
"path": "bank_test.go",
"chars": 8860,
"preview": "package ofxgo\n\nimport (\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n)\n\nfunc TestMarshalBankStatementRequest(t *testing.T) {\n\tvar expec"
},
{
"path": "basic_client.go",
"chars": 3278,
"preview": "package ofxgo\n\nimport (\n\t\"errors\"\n\t\"io\"\n\t\"net/http\"\n\t\"strings\"\n)\n\n// BasicClient provides a standard Client implementati"
},
{
"path": "basic_client_test.go",
"chars": 607,
"preview": "package ofxgo\n\nimport (\n\t\"errors\"\n\t\"net\"\n\t\"net/http\"\n\t\"strings\"\n\t\"testing\"\n)\n\nfunc TestBasicClient_HTTPClient(t *testing"
},
{
"path": "client.go",
"chars": 3576,
"preview": "package ofxgo\n\nimport (\n\t\"io\"\n\t\"net/http\"\n\t\"strings\"\n)\n\n// Client serves to aggregate OFX client settings that may be ne"
},
{
"path": "cmd/ofx/bankdownload.go",
"chars": 2072,
"preview": "package main\n\nimport (\n\t\"flag\"\n\t\"fmt\"\n\t\"github.com/aclindsa/ofxgo\"\n\t\"io\"\n\t\"os\"\n)\n\nvar downloadCommand = command{\n\tName: "
},
{
"path": "cmd/ofx/banktransactions.go",
"chars": 2622,
"preview": "package main\n\nimport (\n\t\"flag\"\n\t\"fmt\"\n\t\"github.com/aclindsa/ofxgo\"\n\t\"os\"\n)\n\nvar bankTransactionsCommand = command{\n\tName"
},
{
"path": "cmd/ofx/ccdownload.go",
"chars": 1648,
"preview": "package main\n\nimport (\n\t\"flag\"\n\t\"fmt\"\n\t\"github.com/aclindsa/ofxgo\"\n\t\"io\"\n\t\"os\"\n)\n\nvar ccDownloadCommand = command{\n\tName"
},
{
"path": "cmd/ofx/cctransactions.go",
"chars": 2101,
"preview": "package main\n\nimport (\n\t\"flag\"\n\t\"fmt\"\n\t\"github.com/aclindsa/ofxgo\"\n\t\"os\"\n)\n\nvar ccTransactionsCommand = command{\n\tName: "
},
{
"path": "cmd/ofx/command.go",
"chars": 2309,
"preview": "package main\n\nimport (\n\t\"flag\"\n\t\"fmt\"\n\t\"golang.org/x/term\"\n\t\"os\"\n)\n\ntype command struct {\n\tName string\n\tDescripti"
},
{
"path": "cmd/ofx/detect_settings.go",
"chars": 4436,
"preview": "package main\n\nimport (\n\t\"flag\"\n\t\"fmt\"\n\t\"github.com/aclindsa/ofxgo\"\n\t\"os\"\n\t\"time\"\n)\n\nvar detectSettingsCommand = command{"
},
{
"path": "cmd/ofx/get_accounts.go",
"chars": 2060,
"preview": "package main\n\nimport (\n\t\"flag\"\n\t\"fmt\"\n\t\"github.com/aclindsa/ofxgo\"\n\t\"os\"\n\t\"time\"\n)\n\nvar getAccountsCommand = command{\n\tN"
},
{
"path": "cmd/ofx/invdownload.go",
"chars": 1950,
"preview": "package main\n\nimport (\n\t\"flag\"\n\t\"fmt\"\n\t\"github.com/aclindsa/ofxgo\"\n\t\"io\"\n\t\"os\"\n)\n\nvar invDownloadCommand = command{\n\tNam"
},
{
"path": "cmd/ofx/invtransactions.go",
"chars": 6555,
"preview": "package main\n\nimport (\n\t\"flag\"\n\t\"fmt\"\n\t\"github.com/aclindsa/ofxgo\"\n\t\"os\"\n)\n\nvar invTransactionsCommand = command{\n\tName:"
},
{
"path": "cmd/ofx/main.go",
"chars": 1395,
"preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"strconv\"\n)\n\nvar commands = []command{\n\tprofileDownloadCommand,\n\tgetAccountsCommand"
},
{
"path": "cmd/ofx/profiledownload.go",
"chars": 1695,
"preview": "package main\n\nimport (\n\t\"flag\"\n\t\"fmt\"\n\t\"github.com/aclindsa/ofxgo\"\n\t\"io\"\n\t\"os\"\n)\n\nvar profileDownloadCommand = command{\n"
},
{
"path": "cmd/ofx/util.go",
"chars": 961,
"preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"github.com/aclindsa/ofxgo\"\n\t\"os\"\n)\n\nfunc newRequest() (ofxgo.Client, *ofxgo.Request) {\n\t"
},
{
"path": "common.go",
"chars": 20064,
"preview": "package ofxgo\n\n//go:generate ./generate_constants.py\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/aclind"
},
{
"path": "common_test.go",
"chars": 1557,
"preview": "package ofxgo\n\nimport (\n\t\"testing\"\n)\n\nfunc TestStatusValid(t *testing.T) {\n\ts := Status{\n\t\tCode: 0,\n\t\tSeverity: \"INF"
},
{
"path": "constants.go",
"chars": 58742,
"preview": "package ofxgo\n\n/*\n * Do not edit this file by hand. It is auto-generated by calling `go generate`.\n * To make changes, e"
},
{
"path": "constants_test.go",
"chars": 68906,
"preview": "package ofxgo\n\n/*\n * Do not edit this file by hand. It is auto-generated by calling `go generate`.\n * To make changes, e"
},
{
"path": "creditcard.go",
"chars": 4095,
"preview": "package ofxgo\n\nimport (\n\t\"github.com/aclindsa/xml\"\n)\n\n// CCStatementRequest represents a request for a credit card state"
},
{
"path": "creditcard_test.go",
"chars": 5257,
"preview": "package ofxgo\n\nimport (\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n)\n\nfunc TestMarshalCCStatementRequest(t *testing.T) {\n\tvar expecte"
},
{
"path": "discovercard_client.go",
"chars": 2812,
"preview": "package ofxgo\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"crypto/tls\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strings\"\n)\n\n// D"
},
{
"path": "doc.go",
"chars": 5880,
"preview": "/*\nPackage ofxgo seeks to provide a library to make it easier to query and/or\nparse financial information with OFX from "
},
{
"path": "generate_constants.py",
"chars": 10104,
"preview": "#!/usr/bin/env python\n\nenums = {\n # OFX spec version\n \"OfxVersion\": ([\"102\", \"103\", \"151\", \"160\", \"200\", \"201\", \"2"
},
{
"path": "go.mod",
"chars": 194,
"preview": "module github.com/aclindsa/ofxgo\n\nrequire (\n\tgithub.com/aclindsa/xml v0.0.0-20201125035057-bbd5c9ec99ac\n\tgolang.org/x/te"
},
{
"path": "go.sum",
"chars": 2935,
"preview": "github.com/aclindsa/xml v0.0.0-20201125035057-bbd5c9ec99ac h1:xCNSfPWpcx3Sdz/+aB/Re4L8oA6Y4kRRRuTh1CHCDEw=\ngithub.com/ac"
},
{
"path": "invstmt.go",
"chars": 70539,
"preview": "package ofxgo\n\nimport (\n\t\"errors\"\n\t\"github.com/aclindsa/xml\"\n)\n\n// InvStatementRequest allows a customer to request tran"
},
{
"path": "invstmt_test.go",
"chars": 48082,
"preview": "package ofxgo\n\nimport (\n\t\"reflect\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/aclindsa/xml\"\n)\n\nfunc TestMarshalInvState"
},
{
"path": "leaf_elements.go",
"chars": 4966,
"preview": "package ofxgo\n\n// A list of all the leaf elements in OFX 1.0.3 (the last SGML version of the\n// spec). These are all the"
},
{
"path": "profile.go",
"chars": 9875,
"preview": "package ofxgo\n\nimport (\n\t\"errors\"\n\t\"github.com/aclindsa/xml\"\n\t\"strings\"\n)\n\n// ProfileRequest represents a request for a "
},
{
"path": "profile_test.go",
"chars": 7364,
"preview": "package ofxgo\n\nimport (\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n)\n\nfunc TestMarshalProfileRequest(t *testing.T) {\n\tvar expectedStr"
},
{
"path": "request.go",
"chars": 4418,
"preview": "package ofxgo\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"github.com/aclindsa/xml\"\n\t\"time\"\n)\n\n// Request is the top-level object mars"
},
{
"path": "request_test.go",
"chars": 1643,
"preview": "package ofxgo\n\nimport (\n\t\"regexp\"\n\t\"strings\"\n\t\"testing\"\n)\n\n// match leading and trailing whitespace on each line\nvar ign"
},
{
"path": "response.go",
"chars": 14538,
"preview": "package ofxgo\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"reflect\"\n\t\"regexp\"\n\t\"strings\"\n\n\t\"github.com/aclindsa/"
},
{
"path": "response_test.go",
"chars": 10185,
"preview": "package ofxgo\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/aclindsa/xm"
},
{
"path": "samples/busted_responses/bmo_v102__no_header_newline.qfx",
"chars": 982,
"preview": "OFXHEADER:100\nDATA:OFXSGML\nVERSION:102\nSECURITY:NONE\nENCODING:USASCII\nCHARSET:1252\nCOMPRESSION:NONE\nOLDFILEUID:NONE\nNEWF"
},
{
"path": "samples/busted_responses/wellsfargo.qfx",
"chars": 973,
"preview": "OFXHEADER:100DATA:OFXSGMLVERSION:102SECURITY:NONEENCODING:USASCIICHARSET:1252COMPRESSION:NONEOLDFILEUID:NONENEWFILEUID:N"
},
{
"path": "samples/valid_responses/401k_v203.ofx",
"chars": 6316,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?><?OFX OFXHEADER=\"200\" VERSION=\"203\" SECURITY=\"NONE\" OLDFILEUID=\"NO"
},
{
"path": "samples/valid_responses/inv_v202.ofx",
"chars": 42104,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\" ?><?OFX OFXHEADER=\"200\" VERSION=\"202\" SECURITY=\"NONE\" OLDFILEUID=\"NONE\" NEWFILEUID="
},
{
"path": "samples/valid_responses/ira_v202.ofx",
"chars": 33923,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\" ?><?OFX OFXHEADER=\"200\" VERSION=\"202\" SECURITY=\"NONE\" OLDFILEUID=\"NONE\" NEWFILEUID="
},
{
"path": "samples/valid_responses/moneymrkt1_v103.ofx",
"chars": 1348,
"preview": "OFXHEADER:100\nDATA:OFXSGML\nVERSION:103\nSECURITY:NONE\nENCODING:USASCII\nCHARSET:1252\nCOMPRESSION:NONE\nOLDFILEUID:NONE\nNEWF"
},
{
"path": "samples/valid_responses/moneymrkt1_v103_TYPE1.ofx",
"chars": 1349,
"preview": "OFXHEADER:100\nDATA:OFXSGML\nVERSION:103\nSECURITY:TYPE1\nENCODING:USASCII\nCHARSET:1252\nCOMPRESSION:NONE\nOLDFILEUID:NONE\nNEW"
},
{
"path": "samples/valid_responses/moneymrkt1_v203.ofx",
"chars": 1864,
"preview": "<?xml version=\"1.0\" encoding=\"utf-16\"?>\n<?OFX OFXHEADER=\"200\" VERSION=\"203\" SECURITY=\"NONE\" OLDFILEUID=\"NONE\" NEWFILEUID"
},
{
"path": "seclist.go",
"chars": 13530,
"preview": "package ofxgo\n\nimport (\n\t\"errors\"\n\t\"github.com/aclindsa/xml\"\n)\n\n// SecurityID identifies a security by its CUSIP (for US"
},
{
"path": "signon.go",
"chars": 3066,
"preview": "package ofxgo\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"github.com/aclindsa/xml\"\n)\n\n// SignonRequest identifies and authenticates a u"
},
{
"path": "signon_test.go",
"chars": 3177,
"preview": "package ofxgo\n\nimport (\n\t\"testing\"\n)\n\nfunc TestMarshalInvalidSignons(t *testing.T) {\n\tvar client = BasicClient{\n\t\tAppID:"
},
{
"path": "signup.go",
"chars": 7486,
"preview": "package ofxgo\n\nimport (\n\t\"fmt\"\n\t\"github.com/aclindsa/xml\"\n)\n\n// AcctInfoRequest represents a request for the server to p"
},
{
"path": "signup_test.go",
"chars": 4042,
"preview": "package ofxgo\n\nimport (\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n)\n\nfunc TestMarshalAcctInfoRequest(t *testing.T) {\n\tvar expectedSt"
},
{
"path": "types.go",
"chars": 10553,
"preview": "package ofxgo\n\nimport (\n\t\"crypto/rand\"\n\t\"errors\"\n\t\"fmt\"\n\t\"github.com/aclindsa/xml\"\n\t\"golang.org/x/text/currency\"\n\t\"math/"
},
{
"path": "types_test.go",
"chars": 16260,
"preview": "package ofxgo\n\nimport (\n\t\"fmt\"\n\t\"github.com/aclindsa/xml\"\n\t\"reflect\"\n\t\"testing\"\n\t\"time\"\n)\n\nfunc getTypeName(i interface{"
},
{
"path": "util.go",
"chars": 579,
"preview": "package ofxgo\n\nimport (\n\t\"bytes\"\n\t\"github.com/aclindsa/xml\"\n)\n\n// Returns the next available Token from the xml.Decoder "
},
{
"path": "vanguard_client.go",
"chars": 4143,
"preview": "package ofxgo\n\nimport (\n\t\"crypto/tls\"\n\t\"errors\"\n\t\"io\"\n\t\"net/http\"\n\t\"strings\"\n)\n\n// VanguardClient provides a Client impl"
}
]
About this extraction
This page contains the full source code of the aclindsa/ofxgo GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 57 files (574.2 KB), approximately 187.0k tokens, and a symbol index with 946 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.