mirror of
				https://github.com/aclindsa/moneygo.git
				synced 2025-10-30 09:33:25 -04:00 
			
		
		
		
	| @@ -10,6 +10,7 @@ import ( | |||||||
| 	"io" | 	"io" | ||||||
| 	"io/ioutil" | 	"io/ioutil" | ||||||
| 	"log" | 	"log" | ||||||
|  | 	"mime/multipart" | ||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"net/http/httptest" | 	"net/http/httptest" | ||||||
| 	"os" | 	"os" | ||||||
| @@ -158,6 +159,61 @@ func remove(client *http.Client, urlsuffix string) error { | |||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func uploadFile(client *http.Client, filename, urlsuffix string) error { | ||||||
|  | 	var buf bytes.Buffer | ||||||
|  | 	mw := multipart.NewWriter(&buf) | ||||||
|  |  | ||||||
|  | 	file, err := os.Open(filename) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	defer file.Close() | ||||||
|  |  | ||||||
|  | 	filewriter, err := mw.CreateFormFile("file", filename) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	if _, err := io.Copy(filewriter, file); err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	mw.Close() | ||||||
|  |  | ||||||
|  | 	response, err := client.Post(server.URL+urlsuffix, mw.FormDataContentType(), &buf) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	body, err := ioutil.ReadAll(response.Body) | ||||||
|  | 	response.Body.Close() | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	var e handlers.Error | ||||||
|  | 	err = (&e).Read(string(body)) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	if e.ErrorId != 0 || len(e.ErrorString) != 0 { | ||||||
|  | 		return &e | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func accountBalanceHelper(t *testing.T, client *http.Client, account *handlers.Account, balance string) { | ||||||
|  | 	t.Helper() | ||||||
|  | 	transactions, err := getAccountTransactions(client, account.AccountId, 0, 0, "") | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatalf("Couldn't fetch account transactions for '%s': %s\n", account.Name, err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if transactions.EndingBalance != balance { | ||||||
|  | 		t.Errorf("Expected ending balance for '%s' to be '%s', but found %s\n", account.Name, balance, transactions.EndingBalance) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| func RunWith(t *testing.T, d *TestData, fn TestDataFunc) { | func RunWith(t *testing.T, d *TestData, fn TestDataFunc) { | ||||||
| 	testdata, err := d.Initialize() | 	testdata, err := d.Initialize() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
|   | |||||||
| @@ -1,69 +1,13 @@ | |||||||
| package handlers_test | package handlers_test | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"bytes" |  | ||||||
| 	"github.com/aclindsa/moneygo/internal/handlers" | 	"github.com/aclindsa/moneygo/internal/handlers" | ||||||
| 	"io" |  | ||||||
| 	"io/ioutil" |  | ||||||
| 	"mime/multipart" |  | ||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"os" |  | ||||||
| 	"testing" | 	"testing" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func importGnucash(client *http.Client, filename string) error { | func importGnucash(client *http.Client, filename string) error { | ||||||
| 	var buf bytes.Buffer | 	return uploadFile(client, filename, "/v1/imports/gnucash") | ||||||
| 	mw := multipart.NewWriter(&buf) |  | ||||||
|  |  | ||||||
| 	file, err := os.Open(filename) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	defer file.Close() |  | ||||||
|  |  | ||||||
| 	filewriter, err := mw.CreateFormFile("gnucash", filename) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	if _, err := io.Copy(filewriter, file); err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	mw.Close() |  | ||||||
|  |  | ||||||
| 	response, err := client.Post(server.URL+"/v1/imports/gnucash", mw.FormDataContentType(), &buf) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	body, err := ioutil.ReadAll(response.Body) |  | ||||||
| 	response.Body.Close() |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	var e handlers.Error |  | ||||||
| 	err = (&e).Read(string(body)) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	if e.ErrorId != 0 || len(e.ErrorString) != 0 { |  | ||||||
| 		return &e |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func gnucashAccountBalanceHelper(t *testing.T, client *http.Client, account *handlers.Account, balance string) { |  | ||||||
| 	t.Helper() |  | ||||||
| 	transactions, err := getAccountTransactions(client, account.AccountId, 0, 0, "") |  | ||||||
| 	if err != nil { |  | ||||||
| 		t.Fatalf("Couldn't fetch account transactions for '%s': %s\n", account.Name, err) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if transactions.EndingBalance != balance { |  | ||||||
| 		t.Errorf("Expected ending balance for '%s' to be '%s', but found %s\n", account.Name, balance, transactions.EndingBalance) |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
|  |  | ||||||
| func TestImportGnucash(t *testing.T) { | func TestImportGnucash(t *testing.T) { | ||||||
| @@ -144,11 +88,11 @@ func TestImportGnucash(t *testing.T) { | |||||||
| 			t.Fatalf("Couldn't find 'Expenses/Cable' account") | 			t.Fatalf("Couldn't find 'Expenses/Cable' account") | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		gnucashAccountBalanceHelper(t, d.clients[0], salary, "-998.34") | 		accountBalanceHelper(t, d.clients[0], salary, "-998.34") | ||||||
| 		gnucashAccountBalanceHelper(t, d.clients[0], creditcard, "-272.03") | 		accountBalanceHelper(t, d.clients[0], creditcard, "-272.03") | ||||||
| 		gnucashAccountBalanceHelper(t, d.clients[0], openingbalances, "-21014.33") | 		accountBalanceHelper(t, d.clients[0], openingbalances, "-21014.33") | ||||||
| 		gnucashAccountBalanceHelper(t, d.clients[0], groceries, "287.56") // 87.19 from preexisting transactions and 200.37 from Gnucash | 		accountBalanceHelper(t, d.clients[0], groceries, "287.56") // 87.19 from preexisting transactions and 200.37 from Gnucash | ||||||
| 		gnucashAccountBalanceHelper(t, d.clients[0], cable, "89.98") | 		accountBalanceHelper(t, d.clients[0], cable, "89.98") | ||||||
|  |  | ||||||
| 		var ge *handlers.Security | 		var ge *handlers.Security | ||||||
| 		securities, err := getSecurities(d.clients[0]) | 		securities, err := getSecurities(d.clients[0]) | ||||||
|   | |||||||
							
								
								
									
										1
									
								
								internal/handlers/handlers_testdata/401k_mutualfunds.ofx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								internal/handlers/handlers_testdata/401k_mutualfunds.ofx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | <?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><MESSAGE>SUCCESS</MESSAGE></STATUS><DTSERVER>20171128203521.622[-5:EST]</DTSERVER><LANGUAGE>ENG</LANGUAGE><FI><ORG>ofx.bank.com</ORG><FID>9199</FID></FI></SONRS></SIGNONMSGSRSV1><INVSTMTMSGSRSV1> <INVSTMTTRNRS><TRNUID>d87db96a-c872-7f73-7637-7e9e2816c25a</TRNUID> <STATUS><CODE>0</CODE><SEVERITY>INFO</SEVERITY><MESSAGE>SUCCESS</MESSAGE></STATUS><INVSTMTRS><DTASOF>20171128193521.926[-5:EST]</DTASOF><CURDEF>USD</CURDEF><INVACCTFROM><BROKERID>ofx.bank.com</BROKERID><ACCTID>12321</ACCTID></INVACCTFROM> <INVTRANLIST><DTSTART>20170829213521.814[-4:EDT]</DTSTART><DTEND>20171127203521.814[-5:EST]</DTEND><BUYMF><INVBUY><INVTRAN><FITID>20170901OAEL011</FITID><DTTRADE>20170901070000.000[-4:EDT]</DTTRADE><MEMO>CONTRIBUTION;VANGUARD TARGET 2045 OAEL;as of 09/01/2017</MEMO></INVTRAN><SECID><UNIQUEID>OAEL</UNIQUEID><UNIQUEIDTYPE>CUSIP</UNIQUEIDTYPE></SECID><UNITS>1.756</UNITS><UNITPRICE>56.97</UNITPRICE><TOTAL>100.05</TOTAL><SUBACCTSEC>OTHER</SUBACCTSEC><SUBACCTFUND>OTHER</SUBACCTFUND></INVBUY><BUYTYPE>BUY</BUYTYPE>    </BUYMF><BUYMF><INVBUY><INVTRAN><FITID>20170915OAEL011</FITID><DTTRADE>20170915070000.000[-4:EDT]</DTTRADE><MEMO>CONTRIBUTION;VANGUARD TARGET 2045 OAEL;as of 09/15/2017</MEMO></INVTRAN><SECID><UNIQUEID>OAEL</UNIQUEID><UNIQUEIDTYPE>CUSIP</UNIQUEIDTYPE></SECID><UNITS>1.737</UNITS><UNITPRICE>57.59</UNITPRICE><TOTAL>100.05</TOTAL><SUBACCTSEC>OTHER</SUBACCTSEC><SUBACCTFUND>OTHER</SUBACCTFUND></INVBUY><BUYTYPE>BUY</BUYTYPE>    </BUYMF><SELLMF><INVSELL><INVTRAN><FITID>20170901OAEL131</FITID><DTTRADE>20170901070000.000[-4:EDT]</DTTRADE><MEMO>FEES;VANGUARD TARGET 2045 OAEL;as of 09/01/2017</MEMO></INVTRAN><SECID><UNIQUEID>OAEL</UNIQUEID><UNIQUEIDTYPE>CUSIP</UNIQUEIDTYPE></SECID><UNITS>0.07</UNITS><UNITPRICE>56.97</UNITPRICE><TOTAL>4.0</TOTAL><SUBACCTSEC>OTHER</SUBACCTSEC><SUBACCTFUND>OTHER</SUBACCTFUND></INVSELL><SELLTYPE>SELL</SELLTYPE>    </SELLMF><SELLMF><INVSELL><INVTRAN><FITID>20171002OAEL131</FITID><DTTRADE>20171002070000.000[-4:EDT]</DTTRADE><MEMO>FEES;VANGUARD TARGET 2045 OAEL;as of 10/02/2017</MEMO></INVTRAN><SECID><UNIQUEID>OAEL</UNIQUEID><UNIQUEIDTYPE>CUSIP</UNIQUEIDTYPE></SECID><UNITS>0.069</UNITS><UNITPRICE>58.1</UNITPRICE><TOTAL>4.0</TOTAL><SUBACCTSEC>OTHER</SUBACCTSEC><SUBACCTFUND>OTHER</SUBACCTFUND></INVSELL><SELLTYPE>SELL</SELLTYPE>    </SELLMF></INVTRANLIST> <INVPOSLIST><POSMF><INVPOS><SECID><UNIQUEID>OAEL</UNIQUEID><UNIQUEIDTYPE>CUSIP</UNIQUEIDTYPE></SECID><HELDINACCT>OTHER</HELDINACCT><POSTYPE>LONG</POSTYPE><UNITS>2792.373</UNITS><UNITPRICE>59.64</UNITPRICE><MKTVAL>200.03</MKTVAL>    <DTPRICEASOF>20171127160000.000[-5:EST]</DTPRICEASOF>   <MEMO>Market close as of 11/27/2017;VANGUARD TARGET 2045</MEMO></INVPOS></POSMF></INVPOSLIST> <INVBAL><AVAILCASH>0</AVAILCASH><MARGINBALANCE>0</MARGINBALANCE><SHORTBALANCE>0</SHORTBALANCE><BALLIST><BAL><NAME>MarketValue</NAME><DESC>MarketValue</DESC><BALTYPE>DOLLAR</BALTYPE><VALUE>200.03</VALUE><DTASOF>20171128193521.926[-5:EST]</DTASOF></BAL><BAL><NAME>VestedValue</NAME><DESC>VestedValue</DESC><BALTYPE>DOLLAR</BALTYPE><VALUE>200.03</VALUE><DTASOF>20171128193521.926[-5:EST]</DTASOF></BAL><BAL><NAME>TotalAssetsValue</NAME><DESC>TotalAssetsValue</DESC><BALTYPE>DOLLAR</BALTYPE><VALUE>200.03</VALUE><DTASOF>20171128193521.926[-5:EST]</DTASOF></BAL></BALLIST></INVBAL><INV401K><EMPLOYERNAME>QC 401(K) PLAN</EMPLOYERNAME></INV401K><INV401KBAL><TOTAL>200.03</TOTAL><BALLIST><BAL><NAME>MarketValue</NAME><DESC>MarketValue</DESC><BALTYPE>DOLLAR</BALTYPE><VALUE>200.03</VALUE><DTASOF>20171128193521.926[-5:EST]</DTASOF></BAL><BAL><NAME>VestedValue</NAME><DESC>VestedValue</DESC><BALTYPE>DOLLAR</BALTYPE><VALUE>200.03</VALUE><DTASOF>20171128193521.926[-5:EST]</DTASOF></BAL><BAL><NAME>TotalAssetsValue</NAME><DESC>TotalAssetsValue</DESC><BALTYPE>DOLLAR</BALTYPE><VALUE>200.03</VALUE><DTASOF>20171128193521.926[-5:EST]</DTASOF></BAL></BALLIST></INV401KBAL></INVSTMTRS></INVSTMTTRNRS></INVSTMTMSGSRSV1> <SECLISTMSGSRSV1><SECLIST><MFINFO><SECINFO><SECID><UNIQUEID>OAEL</UNIQUEID><UNIQUEIDTYPE>CUSIP</UNIQUEIDTYPE></SECID><SECNAME>VANGUARD TARGET 2045</SECNAME><FIID>OAEL</FIID><UNITPRICE>59.64</UNITPRICE><DTASOF>20171127160000.000[-5:EST]</DTASOF><MEMO>Market close as of 11/27/2017;VANGUARD TARGET 2045</MEMO></SECINFO><MFTYPE>OTHER</MFTYPE></MFINFO></SECLIST></SECLISTMSGSRSV1></OFX> | ||||||
							
								
								
									
										11
									
								
								internal/handlers/handlers_testdata/brokerage.ofx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								internal/handlers/handlers_testdata/brokerage.ofx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | |||||||
|  | <?xml version="1.0" encoding="utf-8" ?><?OFX OFXHEADER="200" VERSION="202" SECURITY="NONE" OLDFILEUID="NONE" NEWFILEUID="NONE"?><OFX><SIGNONMSGSRSV1><SONRS><STATUS><CODE>0</CODE><SEVERITY>INFO</SEVERITY><MESSAGE>Successful Sign On</MESSAGE></STATUS><DTSERVER>20171130013742</DTSERVER><LANGUAGE>ENG</LANGUAGE><DTPROFUP>20160713012000</DTPROFUP><FI><ORG>Somewhere</ORG><FID>92772</FID></FI><SESSCOOKIE>01927017240917209172407124984652986</SESSCOOKIE></SONRS></SIGNONMSGSRSV1><INVSTMTMSGSRSV1><INVSTMTTRNRS><TRNUID>a59df4c3-9408-00bb-fd6d-0a06695885b1</TRNUID><STATUS><CODE>0</CODE><SEVERITY>INFO</SEVERITY></STATUS><INVSTMTRS><DTASOF>20171129160000.000[-5:EST]</DTASOF><CURDEF>USD</CURDEF><INVACCTFROM><BROKERID>investing.example.com</BROKERID><ACCTID>73728292</ACCTID></INVACCTFROM><INVTRANLIST><DTSTART>20160529160000.000[-5:EST]160000.000[-5:EST]</DTSTART><DTEND>20171130013742.000[-5:EST]</DTEND> | ||||||
|  | <BUYMF><INVBUY><INVTRAN><FITID>993971056</FITID><DTTRADE>20170315160000.000[-5:EST]</DTTRADE><DTSETTLE>20170316160000.000[-5:EST]</DTSETTLE><MEMO>BUY</MEMO></INVTRAN><SECID><UNIQUEID>921937108</UNIQUEID><UNIQUEIDTYPE>CUSIP</UNIQUEIDTYPE></SECID><UNITS>37.700</UNITS><UNITPRICE>10.61</UNITPRICE><TOTAL>-400.0</TOTAL><SUBACCTSEC>CASH</SUBACCTSEC><SUBACCTFUND>CASH</SUBACCTFUND></INVBUY><BUYTYPE>BUY</BUYTYPE></BUYMF> | ||||||
|  | <BUYSTOCK><INVBUY><INVTRAN><FITID>206046941</FITID><DTTRADE>20160620160000.000[-5:EST]</DTTRADE><DTSETTLE>20160623160000.000[-5:EST]</DTSETTLE><MEMO>BUY</MEMO></INVTRAN><SECID><UNIQUEID>921909768</UNIQUEID><UNIQUEIDTYPE>CUSIP</UNIQUEIDTYPE></SECID><UNITS>15.0</UNITS><UNITPRICE>45.17987</UNITPRICE><TOTAL>-677.70</TOTAL><SUBACCTSEC>CASH</SUBACCTSEC><SUBACCTFUND>CASH</SUBACCTFUND></INVBUY><BUYTYPE>BUY</BUYTYPE></BUYSTOCK> | ||||||
|  | <INCOME><INVTRAN><FITID>63590590</FITID><DTTRADE>20160729160000.000[-5:EST]</DTTRADE><DTSETTLE>20160729160000.000[-5:EST]</DTSETTLE><MEMO>DIVIDEND PAYMENTDIVIDEND PAYMENT</MEMO></INVTRAN><SECID><UNIQUEID>78462F103</UNIQUEID><UNIQUEIDTYPE>CUSIP</UNIQUEIDTYPE></SECID><INCOMETYPE>DIV</INCOMETYPE><TOTAL>1.08</TOTAL><SUBACCTSEC>CASH</SUBACCTSEC><SUBACCTFUND>CASH</SUBACCTFUND></INCOME> | ||||||
|  | <REINVEST><INVTRAN><FITID>769223517</FITID><DTTRADE>20160606160000.000[-5:EST]</DTTRADE><DTSETTLE>20160606160000.000[-5:EST]</DTSETTLE><MEMO>DIVIDEND REINVESTMENTDIVIDEND REINVESTMENT</MEMO></INVTRAN><SECID><UNIQUEID>049560105</UNIQUEID><UNIQUEIDTYPE>CUSIP</UNIQUEIDTYPE></SECID><INCOMETYPE>DIV</INCOMETYPE><TOTAL>-6.43</TOTAL><SUBACCTSEC>CASH</SUBACCTSEC><UNITS>0.086</UNITS><UNITPRICE>74.9777</UNITPRICE></REINVEST> | ||||||
|  | <SELLMF><INVSELL><INVTRAN><FITID>619689018</FITID><DTTRADE>20160627160000.000[-5:EST]</DTTRADE><DTSETTLE>20160627160000.000[-5:EST]</DTSETTLE><MEMO>MONEY FUND REDEMPTION</MEMO></INVTRAN><SECID><UNIQUEID>922906300</UNIQUEID><UNIQUEIDTYPE>CUSIP</UNIQUEIDTYPE></SECID><UNITS>-21.57</UNITS><UNITPRICE>1.0</UNITPRICE><TOTAL>21.57</TOTAL><SUBACCTSEC>CASH</SUBACCTSEC><SUBACCTFUND>CASH</SUBACCTFUND></INVSELL><SELLTYPE>SELL</SELLTYPE></SELLMF> | ||||||
|  | <SELLSTOCK><INVSELL><INVTRAN><FITID>328444499</FITID><DTTRADE>20160708160000.000[-5:EST]</DTTRADE><DTSETTLE>20160713160000.000[-5:EST]</DTSETTLE><MEMO>SELL</MEMO></INVTRAN><SECID><UNIQUEID>921909768</UNIQUEID><UNIQUEIDTYPE>CUSIP</UNIQUEIDTYPE></SECID><UNITS>-10.0</UNITS><UNITPRICE>44.26013</UNITPRICE><FEES>0.07</FEES><TOTAL>442.53</TOTAL><SUBACCTSEC>CASH</SUBACCTSEC><SUBACCTFUND>CASH</SUBACCTFUND></INVSELL><SELLTYPE>SELL</SELLTYPE></SELLSTOCK> | ||||||
|  | <INVBANKTRAN><STMTTRN><TRNTYPE>OTHER</TRNTYPE><DTPOSTED>20160607160000.000[-5:EST]</DTPOSTED><TRNAMT>1000.0</TRNAMT><FITID>230048208</FITID></STMTTRN><SUBACCTFUND>CASH</SUBACCTFUND></INVBANKTRAN> | ||||||
|  | </INVTRANLIST> | ||||||
|  | <INVPOSLIST><POSSTOCK><INVPOS><SECID><UNIQUEID>049560105</UNIQUEID><UNIQUEIDTYPE>CUSIP</UNIQUEIDTYPE></SECID><HELDINACCT>CASH</HELDINACCT><POSTYPE>LONG</POSTYPE><UNITS>6.086</UNITS><UNITPRICE>90.51</UNITPRICE><MKTVAL>550.843</MKTVAL><DTPRICEASOF>20171128160000.000[-5:EST]</DTPRICEASOF><MEMO>Price as of date based on closing price</MEMO></INVPOS><REINVDIV>Y</REINVDIV></POSSTOCK><POSMF><INVPOS><SECID><UNIQUEID>921937108</UNIQUEID><UNIQUEIDTYPE>CUSIP</UNIQUEIDTYPE></SECID><HELDINACCT>CASH</HELDINACCT><POSTYPE>LONG</POSTYPE><UNITS>37.77</UNITS><UNITPRICE>10.75</UNITPRICE><MKTVAL>406.02</MKTVAL><DTPRICEASOF>20171128160000.000[-5:EST]</DTPRICEASOF><MEMO>Price as of date based on closing price</MEMO></INVPOS><REINVDIV>Y</REINVDIV><REINVCG>Y</REINVCG></POSMF><POSMF><INVPOS><SECID><UNIQUEID>922906300</UNIQUEID><UNIQUEIDTYPE>CUSIP</UNIQUEIDTYPE></SECID><HELDINACCT>CASH</HELDINACCT><POSTYPE>LONG</POSTYPE><UNITS>24.87</UNITS><UNITPRICE>1.0</UNITPRICE><MKTVAL>24.87</MKTVAL><DTPRICEASOF>20171128160000.000[-5:EST]</DTPRICEASOF><MEMO>Price as of date based on closing price</MEMO></INVPOS><REINVDIV>N</REINVDIV><REINVCG>N</REINVCG></POSMF></INVPOSLIST> | ||||||
|  | <INVBAL><AVAILCASH>387.48</AVAILCASH><MARGINBALANCE>0.0</MARGINBALANCE><SHORTBALANCE>0.0</SHORTBALANCE></INVBAL></INVSTMTRS></INVSTMTTRNRS></INVSTMTMSGSRSV1><SECLISTMSGSRSV1><SECLIST><STOCKINFO><SECINFO><SECID><UNIQUEID>049560105</UNIQUEID><UNIQUEIDTYPE>CUSIP</UNIQUEIDTYPE></SECID><SECNAME>ATMOS ENERGY CORP</SECNAME><TICKER>ATO</TICKER><UNITPRICE>90.51</UNITPRICE><MEMO>Price as of date based on closing price</MEMO></SECINFO><STOCKTYPE>COMMON</STOCKTYPE><YIELD>2.1491</YIELD></STOCKINFO><STOCKINFO><SECINFO><SECID><UNIQUEID>921909768</UNIQUEID><UNIQUEIDTYPE>CUSIP</UNIQUEIDTYPE></SECID><SECNAME>VANGUARD TOTAL INTL STOCK INDE</SECNAME><TICKER>921909768</TICKER><MEMO>BUY</MEMO></SECINFO></STOCKINFO><STOCKINFO><SECINFO><SECID><UNIQUEID>78462F103</UNIQUEID><UNIQUEIDTYPE>CUSIP</UNIQUEIDTYPE></SECID><SECNAME>20SPDR SP 500 ETF</SECNAME><TICKER>78462F103</TICKER><MEMO>SELL</MEMO></SECINFO></STOCKINFO><MFINFO><SECINFO><SECID><UNIQUEID>921937108</UNIQUEID><UNIQUEIDTYPE>CUSIP</UNIQUEIDTYPE></SECID><SECNAME>Vanguard Total Bond Market Index Fund Investor Shares</SECNAME><TICKER>VBMFX</TICKER><UNITPRICE>10.75</UNITPRICE><MEMO>Price as of date based on closing price</MEMO></SECINFO><MFTYPE>OPENEND</MFTYPE></MFINFO><MFINFO><SECINFO><SECID><UNIQUEID>922906300</UNIQUEID><UNIQUEIDTYPE>CUSIP</UNIQUEIDTYPE></SECID><SECNAME>Vanguard Federal Money Market Fund</SECNAME><TICKER>VMFXX</TICKER><UNITPRICE>1.0</UNITPRICE><MEMO>Price as of date based on closing price</MEMO></SECINFO><MFTYPE>OPENEND</MFTYPE></MFINFO></SECLIST></SECLISTMSGSRSV1></OFX> | ||||||
							
								
								
									
										140
									
								
								internal/handlers/handlers_testdata/checking_20171126.ofx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										140
									
								
								internal/handlers/handlers_testdata/checking_20171126.ofx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,140 @@ | |||||||
|  | <?xml version="1.0" encoding="utf-16"?> | ||||||
|  | <?OFX OFXHEADER="200" VERSION="203" SECURITY="NONE" OLDFILEUID="NONE" NEWFILEUID="NONE"?> | ||||||
|  | <OFX> | ||||||
|  |   <SIGNONMSGSRSV1><SONRS> | ||||||
|  |   <STATUS> | ||||||
|  |     <CODE>0</CODE> | ||||||
|  |     <SEVERITY>INFO</SEVERITY> | ||||||
|  |   </STATUS> | ||||||
|  |   <DTSERVER>20171126184401.091[0:GMT]</DTSERVER> | ||||||
|  |   <LANGUAGE>ENG</LANGUAGE> | ||||||
|  |   <FI> | ||||||
|  |     <ORG>YCKVJ</ORG> | ||||||
|  |     <FID>0351</FID> | ||||||
|  |   </FI> | ||||||
|  | </SONRS></SIGNONMSGSRSV1> | ||||||
|  |   <BANKMSGSRSV1> | ||||||
|  |     <STMTTRNRS> | ||||||
|  |       <TRNUID>0549c828-f02c-43c7-81a3-de0b3f23c393</TRNUID> | ||||||
|  | <STATUS> | ||||||
|  |   <CODE>0</CODE> | ||||||
|  |   <SEVERITY>INFO</SEVERITY> | ||||||
|  | </STATUS> | ||||||
|  | <STMTRS> | ||||||
|  |   <CURDEF>USD</CURDEF> | ||||||
|  |   <BANKACCTFROM> | ||||||
|  |     <BANKID>115483849</BANKID> | ||||||
|  |     <ACCTID>14839128817</ACCTID> | ||||||
|  |     <ACCTTYPE>CHECKING</ACCTTYPE> | ||||||
|  |   </BANKACCTFROM> | ||||||
|  |   <BANKTRANLIST> | ||||||
|  |     <DTSTART>20170828174401.637[0:GMT]</DTSTART> | ||||||
|  |     <DTEND>20171126184401.637[0:GMT]</DTEND> | ||||||
|  |     <STMTTRN> | ||||||
|  |       <TRNTYPE>CREDIT</TRNTYPE> | ||||||
|  |       <DTPOSTED>20170830120000.000[0:GMT]</DTPOSTED> | ||||||
|  |       <TRNAMT>2843.08</TRNAMT> | ||||||
|  |       <FITID>ce2cf749-dd15-4dc7-b78d-2f9e88d8a702</FITID> | ||||||
|  |       <NAME>SALARY</NAME> | ||||||
|  |       <MEMO>ACH Deposit 18181818199</MEMO> | ||||||
|  |     </STMTTRN> | ||||||
|  |     <STMTTRN> | ||||||
|  |       <TRNTYPE>DEBIT</TRNTYPE> | ||||||
|  |       <DTPOSTED>20170830120000.000[0:GMT]</DTPOSTED> | ||||||
|  |       <TRNAMT>-2354.66</TRNAMT> | ||||||
|  |       <FITID>2bda11f4-9a9c-43fb-b67a-71f747dcf684</FITID> | ||||||
|  |       <NAME>BILLPAY TO CREDIT CARD</NAME> | ||||||
|  |       <MEMO>ACH Debit 8181819191919</MEMO> | ||||||
|  |     </STMTTRN> | ||||||
|  |     <STMTTRN> | ||||||
|  |       <TRNTYPE>CHECK</TRNTYPE> | ||||||
|  |       <DTPOSTED>20170830120000.000[0:GMT]</DTPOSTED> | ||||||
|  |       <TRNAMT>-15.00</TRNAMT> | ||||||
|  |       <FITID>62dcc92d-ba0f-4fe6-8611-d6c1b86594fc</FITID> | ||||||
|  |       <CHECKNUM>3304</CHECKNUM> | ||||||
|  |       <NAME>Check</NAME> | ||||||
|  |       <MEMO>INCLEARING CHECK</MEMO> | ||||||
|  |     </STMTTRN> | ||||||
|  |     <STMTTRN> | ||||||
|  |       <TRNTYPE>DEBIT</TRNTYPE> | ||||||
|  |       <DTPOSTED>20171107120000.000[0:GMT]</DTPOSTED> | ||||||
|  |       <TRNAMT>-282.68</TRNAMT> | ||||||
|  |       <FITID>29c74a94-f226-4980-b54c-da6fa2721d7e</FITID> | ||||||
|  |       <NAME>DAYCARE o SIGONFILE</NAME> | ||||||
|  |       <MEMO>ACH Debit 11818191919191</MEMO> | ||||||
|  |     </STMTTRN> | ||||||
|  |     <STMTTRN> | ||||||
|  |       <TRNTYPE>CREDIT</TRNTYPE> | ||||||
|  |       <DTPOSTED>20171109120000.000[0:GMT]</DTPOSTED> | ||||||
|  |       <TRNAMT>1300.98</TRNAMT> | ||||||
|  |       <FITID>32e40e98-61c3-421c-acaa-55ae67a5f8fe</FITID> | ||||||
|  |       <NAME>DIRECT DEPOSIT</NAME> | ||||||
|  |       <MEMO>ACH Deposit 8282828282828</MEMO> | ||||||
|  |     </STMTTRN> | ||||||
|  |     <STMTTRN> | ||||||
|  |       <TRNTYPE>DEBIT</TRNTYPE> | ||||||
|  |       <DTPOSTED>20171109120000.000[0:GMT]</DTPOSTED> | ||||||
|  |       <TRNAMT>-98.20</TRNAMT> | ||||||
|  |       <FITID>4b73dbbf-aa27-4f62-b54a-ee0a9a3486d8</FITID> | ||||||
|  |       <NAME>DUKEENGYPROGRESS DUKEENGYPR</NAME> | ||||||
|  |       <MEMO>ACH Debit 017313004099621</MEMO> | ||||||
|  |     </STMTTRN> | ||||||
|  |     <STMTTRN> | ||||||
|  |       <TRNTYPE>CREDIT</TRNTYPE> | ||||||
|  |       <DTPOSTED>20171115120000.000[0:GMT]</DTPOSTED> | ||||||
|  |       <TRNAMT>1.01</TRNAMT> | ||||||
|  |       <FITID>51c47252-4cf0-442c-b619-8a31b17ac489</FITID> | ||||||
|  |       <NAME>Dividend Earned</NAME> | ||||||
|  |     </STMTTRN> | ||||||
|  |     <STMTTRN> | ||||||
|  |       <TRNTYPE>DEBIT</TRNTYPE> | ||||||
|  |       <DTPOSTED>20171116120000.000[0:GMT]</DTPOSTED> | ||||||
|  |       <TRNAMT>-51.75</TRNAMT> | ||||||
|  |       <FITID>51cb12bb-cdd9-4333-8d8d-c423f9e8f833</FITID> | ||||||
|  |       <NAME>TARGET DEBIT CRD    ACH TRAN</NAME> | ||||||
|  |       <MEMO>ACH Debit</MEMO> | ||||||
|  |     </STMTTRN> | ||||||
|  |     <STMTTRN> | ||||||
|  |       <TRNTYPE>DEBIT</TRNTYPE> | ||||||
|  |       <DTPOSTED>20171120120000.000[0:GMT]</DTPOSTED> | ||||||
|  |       <TRNAMT>-25.18</TRNAMT> | ||||||
|  |       <FITID>366a5b23-2f2e-4cf0-a714-6a306bd4e909</FITID> | ||||||
|  |       <NAME>TARGET DEBIT CRD    ACH TRAN</NAME> | ||||||
|  |       <MEMO>ACH Debit</MEMO> | ||||||
|  |     </STMTTRN> | ||||||
|  |     <STMTTRN> | ||||||
|  |       <TRNTYPE>DEBIT</TRNTYPE> | ||||||
|  |       <DTPOSTED>20171121120000.000[0:GMT]</DTPOSTED> | ||||||
|  |       <TRNAMT>-10.71</TRNAMT> | ||||||
|  |       <FITID>9a463f21-c6e1-4fe0-b37b-f9a8cc942cf0</FITID> | ||||||
|  |       <NAME>NETFLIX COM       NETFLIX COM</NAME> | ||||||
|  |       <MEMO>Point of Sale Debit L999 DATE 11-20</MEMO> | ||||||
|  |     </STMTTRN> | ||||||
|  |     <STMTTRN> | ||||||
|  |       <TRNTYPE>CREDIT</TRNTYPE> | ||||||
|  |       <DTPOSTED>20171122120000.000[0:GMT]</DTPOSTED> | ||||||
|  |       <TRNAMT>1300.98</TRNAMT> | ||||||
|  |       <FITID>31f165e5-569f-4530-8438-a6ceb2301335</FITID> | ||||||
|  |       <NAME>DIRECT DEPOSIT</NAME> | ||||||
|  |       <MEMO>ACH Deposit 838383838383838</MEMO> | ||||||
|  |     </STMTTRN> | ||||||
|  |     <STMTTRN> | ||||||
|  |       <TRNTYPE>CREDIT</TRNTYPE> | ||||||
|  |       <DTPOSTED>20171122120000.000[0:GMT]</DTPOSTED> | ||||||
|  |       <TRNAMT>12.50</TRNAMT> | ||||||
|  |       <FITID>215a10dd-f3a2-4336-ab8c-f22276cad552</FITID> | ||||||
|  |       <NAME>CIRCLE INTERNET  CIRCLE</NAME> | ||||||
|  |       <MEMO>ACH Deposit 017326000283477</MEMO> | ||||||
|  |     </STMTTRN> | ||||||
|  |   </BANKTRANLIST> | ||||||
|  |   <LEDGERBAL> | ||||||
|  |     <BALAMT>2620.37</BALAMT> | ||||||
|  |     <DTASOF>20171126184401.637[0:GMT]</DTASOF> | ||||||
|  |   </LEDGERBAL> | ||||||
|  |   <AVAILBAL> | ||||||
|  |     <BALAMT>3620.37</BALAMT> | ||||||
|  |     <DTASOF>20171126184401.637[0:GMT]</DTASOF> | ||||||
|  |   </AVAILBAL> | ||||||
|  | </STMTRS></STMTTRNRS> | ||||||
|  |   </BANKMSGSRSV1> | ||||||
|  | </OFX> | ||||||
							
								
								
									
										123
									
								
								internal/handlers/handlers_testdata/checking_20171129.ofx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								internal/handlers/handlers_testdata/checking_20171129.ofx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,123 @@ | |||||||
|  | <?xml version="1.0" encoding="utf-16"?> | ||||||
|  | <?OFX OFXHEADER="200" VERSION="203" SECURITY="NONE" OLDFILEUID="NONE" NEWFILEUID="NONE"?> | ||||||
|  | <OFX> | ||||||
|  |   <SIGNONMSGSRSV1><SONRS> | ||||||
|  |   <STATUS> | ||||||
|  |     <CODE>0</CODE> | ||||||
|  |     <SEVERITY>INFO</SEVERITY> | ||||||
|  |   </STATUS> | ||||||
|  |   <DTSERVER>20171129025346.132[0:GMT]</DTSERVER> | ||||||
|  |   <LANGUAGE>ENG</LANGUAGE> | ||||||
|  |   <FI> | ||||||
|  |     <ORG>YCKVJ</ORG> | ||||||
|  |     <FID>0351</FID> | ||||||
|  |   </FI> | ||||||
|  | </SONRS></SIGNONMSGSRSV1> | ||||||
|  |   <BANKMSGSRSV1> | ||||||
|  |     <STMTTRNRS> | ||||||
|  |       <TRNUID>0549c828-f02c-43c7-81a3-de0b3f23c393</TRNUID> | ||||||
|  | <STATUS> | ||||||
|  |   <CODE>0</CODE> | ||||||
|  |   <SEVERITY>INFO</SEVERITY> | ||||||
|  | </STATUS> | ||||||
|  | <STMTRS> | ||||||
|  |   <CURDEF>USD</CURDEF> | ||||||
|  |   <BANKACCTFROM> | ||||||
|  |     <BANKID>115483849</BANKID> | ||||||
|  |     <ACCTID>14839128817</ACCTID> | ||||||
|  |     <ACCTTYPE>CHECKING</ACCTTYPE> | ||||||
|  |   </BANKACCTFROM> | ||||||
|  |   <BANKTRANLIST> | ||||||
|  |     <DTSTART>20170831174401.637[0:GMT]</DTSTART> | ||||||
|  |     <DTEND>20171129184401.637[0:GMT]</DTEND> | ||||||
|  |     <STMTTRN> | ||||||
|  |       <TRNTYPE>DEBIT</TRNTYPE> | ||||||
|  |       <DTPOSTED>20171107120000.000[0:GMT]</DTPOSTED> | ||||||
|  |       <TRNAMT>-282.68</TRNAMT> | ||||||
|  |       <FITID>29c74a94-f226-4980-b54c-da6fa2721d7e</FITID> | ||||||
|  |       <NAME>DAYCARE o SIGONFILE</NAME> | ||||||
|  |       <MEMO>ACH Debit 11818191919191</MEMO> | ||||||
|  |     </STMTTRN> | ||||||
|  |     <STMTTRN> | ||||||
|  |       <TRNTYPE>CREDIT</TRNTYPE> | ||||||
|  |       <DTPOSTED>20171109120000.000[0:GMT]</DTPOSTED> | ||||||
|  |       <TRNAMT>1300.98</TRNAMT> | ||||||
|  |       <FITID>32e40e98-61c3-421c-acaa-55ae67a5f8fe</FITID> | ||||||
|  |       <NAME>DIRECT DEPOSIT</NAME> | ||||||
|  |       <MEMO>ACH Deposit 8282828282828</MEMO> | ||||||
|  |     </STMTTRN> | ||||||
|  |     <STMTTRN> | ||||||
|  |       <TRNTYPE>DEBIT</TRNTYPE> | ||||||
|  |       <DTPOSTED>20171109120000.000[0:GMT]</DTPOSTED> | ||||||
|  |       <TRNAMT>-98.20</TRNAMT> | ||||||
|  |       <FITID>4b73dbbf-aa27-4f62-b54a-ee0a9a3486d8</FITID> | ||||||
|  |       <NAME>DUKEENGYPROGRESS DUKEENGYPR</NAME> | ||||||
|  |       <MEMO>ACH Debit 017313004099621</MEMO> | ||||||
|  |     </STMTTRN> | ||||||
|  |     <STMTTRN> | ||||||
|  |       <TRNTYPE>CREDIT</TRNTYPE> | ||||||
|  |       <DTPOSTED>20171115120000.000[0:GMT]</DTPOSTED> | ||||||
|  |       <TRNAMT>1.01</TRNAMT> | ||||||
|  |       <FITID>51c47252-4cf0-442c-b619-8a31b17ac489</FITID> | ||||||
|  |       <NAME>Dividend Earned</NAME> | ||||||
|  |     </STMTTRN> | ||||||
|  |     <STMTTRN> | ||||||
|  |       <TRNTYPE>DEBIT</TRNTYPE> | ||||||
|  |       <DTPOSTED>20171116120000.000[0:GMT]</DTPOSTED> | ||||||
|  |       <TRNAMT>-51.75</TRNAMT> | ||||||
|  |       <FITID>51cb12bb-cdd9-4333-8d8d-c423f9e8f833</FITID> | ||||||
|  |       <NAME>TARGET DEBIT CRD    ACH TRAN</NAME> | ||||||
|  |       <MEMO>ACH Debit</MEMO> | ||||||
|  |     </STMTTRN> | ||||||
|  |     <STMTTRN> | ||||||
|  |       <TRNTYPE>DEBIT</TRNTYPE> | ||||||
|  |       <DTPOSTED>20171120120000.000[0:GMT]</DTPOSTED> | ||||||
|  |       <TRNAMT>-25.18</TRNAMT> | ||||||
|  |       <FITID>366a5b23-2f2e-4cf0-a714-6a306bd4e909</FITID> | ||||||
|  |       <NAME>TARGET DEBIT CRD    ACH TRAN</NAME> | ||||||
|  |       <MEMO>ACH Debit</MEMO> | ||||||
|  |     </STMTTRN> | ||||||
|  |     <STMTTRN> | ||||||
|  |       <TRNTYPE>DEBIT</TRNTYPE> | ||||||
|  |       <DTPOSTED>20171121120000.000[0:GMT]</DTPOSTED> | ||||||
|  |       <TRNAMT>-10.71</TRNAMT> | ||||||
|  |       <FITID>9a463f21-c6e1-4fe0-b37b-f9a8cc942cf0</FITID> | ||||||
|  |       <NAME>NETFLIX COM       NETFLIX COM</NAME> | ||||||
|  |       <MEMO>Point of Sale Debit L999 DATE 11-20</MEMO> | ||||||
|  |     </STMTTRN> | ||||||
|  |     <STMTTRN> | ||||||
|  |       <TRNTYPE>CREDIT</TRNTYPE> | ||||||
|  |       <DTPOSTED>20171122120000.000[0:GMT]</DTPOSTED> | ||||||
|  |       <TRNAMT>1300.98</TRNAMT> | ||||||
|  |       <FITID>31f165e5-569f-4530-8438-a6ceb2301335</FITID> | ||||||
|  |       <NAME>DIRECT DEPOSIT</NAME> | ||||||
|  |       <MEMO>ACH Deposit 838383838383838</MEMO> | ||||||
|  |     </STMTTRN> | ||||||
|  |     <STMTTRN> | ||||||
|  |       <TRNTYPE>CREDIT</TRNTYPE> | ||||||
|  |       <DTPOSTED>20171122120000.000[0:GMT]</DTPOSTED> | ||||||
|  |       <TRNAMT>12.50</TRNAMT> | ||||||
|  |       <FITID>215a10dd-f3a2-4336-ab8c-f22276cad552</FITID> | ||||||
|  |       <NAME>CIRCLE INTERNET  CIRCLE</NAME> | ||||||
|  |       <MEMO>ACH Deposit 017326000283477</MEMO> | ||||||
|  |     </STMTTRN> | ||||||
|  |     <STMTTRN> | ||||||
|  |       <TRNTYPE>CREDIT</TRNTYPE> | ||||||
|  |       <DTPOSTED>20171129120000.000[0:GMT]</DTPOSTED> | ||||||
|  |       <TRNAMT>2843.08</TRNAMT> | ||||||
|  |       <FITID>9a52df4b-3a8d-41bb-9141-96e1e3f294cf</FITID> | ||||||
|  |       <NAME>SALARY</NAME> | ||||||
|  |       <MEMO>ACH Deposit 18181818199</MEMO> | ||||||
|  |     </STMTTRN> | ||||||
|  |   </BANKTRANLIST> | ||||||
|  |   <LEDGERBAL> | ||||||
|  |     <BALAMT>5463.45</BALAMT> | ||||||
|  |     <DTASOF>20171129025346.132[0:GMT]</DTASOF> | ||||||
|  |   </LEDGERBAL> | ||||||
|  |   <AVAILBAL> | ||||||
|  |     <BALAMT>6463.45</BALAMT> | ||||||
|  |     <DTASOF>20171129025346.132[0:GMT]</DTASOF> | ||||||
|  |   </AVAILBAL> | ||||||
|  | </STMTRS></STMTTRNRS> | ||||||
|  |   </BANKMSGSRSV1> | ||||||
|  | </OFX> | ||||||
							
								
								
									
										11
									
								
								internal/handlers/handlers_testdata/creditcard.ofx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								internal/handlers/handlers_testdata/creditcard.ofx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | |||||||
|  | OFXHEADER:100 | ||||||
|  | DATA:OFXSGML | ||||||
|  | VERSION:102 | ||||||
|  | SECURITY:NONE | ||||||
|  | ENCODING:USASCII | ||||||
|  | CHARSET:1252 | ||||||
|  | COMPRESSION:NONE | ||||||
|  | OLDFILEUID:NONE | ||||||
|  | NEWFILEUID:NONE | ||||||
|  |  | ||||||
|  | <OFX><SIGNONMSGSRSV1><SONRS><STATUS><CODE>0<SEVERITY>INFO<MESSAGE>SUCCESS</STATUS><DTSERVER>20171128054239.013[-5:EST]<LANGUAGE>ENG<FI><ORG>C2<FID>29292</FI></SONRS></SIGNONMSGSRSV1><CREDITCARDMSGSRSV1><CCSTMTTRNRS><TRNUID>1cc61e4b-1f74-7d9a-b143-b8c80d5fda58<STATUS><CODE>0<SEVERITY>INFO</STATUS><CCSTMTRS><CURDEF>USD<CCACCTFROM><ACCTID>1234123412341234</CCACCTFROM><BANKTRANLIST><DTSTART>20170731054239.277[-4:EDT]<DTEND>20171128054239.277[-5:EST]<STMTTRN><TRNTYPE>DEBIT<DTPOSTED>20171016120000[0:GMT]<TRNAMT>-99.98<FITID>2017101624445727288300440999736<NAME>KROGER #111</STMTTRN><STMTTRN><TRNTYPE>DEBIT<DTPOSTED>20170910120000[0:GMT]<TRNAMT>-150<FITID>2017091024493987251438675718282<NAME>CHARITY DONATION</STMTTRN><STMTTRN><TRNTYPE>DEBIT<DTPOSTED>20170814120000[0:GMT]<TRNAMT>-44.99<FITID>2017081424692167225100642481235<NAME>CABLE</STMTTRN><STMTTRN><TRNTYPE>CREDIT<DTPOSTED>20171101120000[0:GMT]<TRNAMT>185.71<FITID>2017110123053057200000291455612<NAME>Payment Thank You Electro</STMTTRN><STMTTRN><TRNTYPE>DEBIT<DTPOSTED>20171016120000[0:GMT]<TRNAMT>-4.49<FITID>2017101624510727289100677772726<NAME>CRAFTS</STMTTRN><STMTTRN><TRNTYPE>CREDIT<DTPOSTED>20170815120000[0:GMT]<TRNAMT>109.26<FITID>2017081574692167226100322807539<NAME>Example.com</STMTTRN></BANKTRANLIST><LEDGERBAL><BALAMT>-4.49<DTASOF>20171128070000.000[-5:EST]</LEDGERBAL><AVAILBAL><BALAMT>995.51<DTASOF>20171128070000.000[-5:EST]</AVAILBAL></CCSTMTRS></CCSTMTTRNRS></CREDITCARDMSGSRSV1></OFX> | ||||||
| @@ -228,11 +228,13 @@ func (i *OFXImport) GetInvBuyTran(buy *ofxgo.InvBuy, curdef *Security, account * | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	var commission, taxes, fees, load, total, tradingTotal big.Rat | 	var commission, taxes, fees, load, total, tradingTotal big.Rat | ||||||
| 	commission.Set(&buy.Commission.Rat) | 	commission.Abs(&buy.Commission.Rat) | ||||||
| 	taxes.Set(&buy.Taxes.Rat) | 	taxes.Abs(&buy.Taxes.Rat) | ||||||
| 	fees.Set(&buy.Fees.Rat) | 	fees.Abs(&buy.Fees.Rat) | ||||||
| 	load.Set(&buy.Load.Rat) | 	load.Abs(&buy.Load.Rat) | ||||||
| 	total.Set(&buy.Total.Rat) | 	total.Abs(&buy.Total.Rat) | ||||||
|  |  | ||||||
|  | 	total.Neg(&total) | ||||||
|  |  | ||||||
| 	tradingTotal.Neg(&total) | 	tradingTotal.Neg(&total) | ||||||
| 	tradingTotal.Sub(&tradingTotal, &commission) | 	tradingTotal.Sub(&tradingTotal, &commission) | ||||||
| @@ -319,8 +321,8 @@ func (i *OFXImport) GetInvBuyTran(buy *ofxgo.InvBuy, curdef *Security, account * | |||||||
| 		Amount:          tradingTotal.FloatString(curdef.Precision), | 		Amount:          tradingTotal.FloatString(curdef.Precision), | ||||||
| 	}) | 	}) | ||||||
|  |  | ||||||
| 	units := big.NewRat(0, 1) | 	var units big.Rat | ||||||
| 	units.Set(&buy.Units.Rat) | 	units.Abs(&buy.Units.Rat) | ||||||
| 	t.Splits = append(t.Splits, &Split{ | 	t.Splits = append(t.Splits, &Split{ | ||||||
| 		// TODO ReversalFiTID? | 		// TODO ReversalFiTID? | ||||||
| 		Status:          Imported, | 		Status:          Imported, | ||||||
| @@ -331,7 +333,7 @@ func (i *OFXImport) GetInvBuyTran(buy *ofxgo.InvBuy, curdef *Security, account * | |||||||
| 		Memo:            memo, | 		Memo:            memo, | ||||||
| 		Amount:          units.FloatString(security.Precision), | 		Amount:          units.FloatString(security.Precision), | ||||||
| 	}) | 	}) | ||||||
| 	units.Neg(units) | 	units.Neg(&units) | ||||||
| 	t.Splits = append(t.Splits, &Split{ | 	t.Splits = append(t.Splits, &Split{ | ||||||
| 		// TODO ReversalFiTID? | 		// TODO ReversalFiTID? | ||||||
| 		Status:          Imported, | 		Status:          Imported, | ||||||
| @@ -490,11 +492,13 @@ func (i *OFXImport) GetReinvestTran(reinvest *ofxgo.Reinvest, curdef *Security, | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	var commission, taxes, fees, load, total, tradingTotal big.Rat | 	var commission, taxes, fees, load, total, tradingTotal big.Rat | ||||||
| 	commission.Set(&reinvest.Commission.Rat) | 	commission.Abs(&reinvest.Commission.Rat) | ||||||
| 	taxes.Set(&reinvest.Taxes.Rat) | 	taxes.Abs(&reinvest.Taxes.Rat) | ||||||
| 	fees.Set(&reinvest.Fees.Rat) | 	fees.Abs(&reinvest.Fees.Rat) | ||||||
| 	load.Set(&reinvest.Load.Rat) | 	load.Abs(&reinvest.Load.Rat) | ||||||
| 	total.Set(&reinvest.Total.Rat) | 	total.Abs(&reinvest.Total.Rat) | ||||||
|  |  | ||||||
|  | 	total.Neg(&total) | ||||||
|  |  | ||||||
| 	tradingTotal.Neg(&total) | 	tradingTotal.Neg(&total) | ||||||
| 	tradingTotal.Sub(&tradingTotal, &commission) | 	tradingTotal.Sub(&tradingTotal, &commission) | ||||||
| @@ -604,7 +608,7 @@ func (i *OFXImport) GetReinvestTran(reinvest *ofxgo.Reinvest, curdef *Security, | |||||||
| 	}) | 	}) | ||||||
|  |  | ||||||
| 	var units big.Rat | 	var units big.Rat | ||||||
| 	units.Set(&reinvest.Units.Rat) | 	units.Abs(&reinvest.Units.Rat) | ||||||
| 	t.Splits = append(t.Splits, &Split{ | 	t.Splits = append(t.Splits, &Split{ | ||||||
| 		// TODO ReversalFiTID? | 		// TODO ReversalFiTID? | ||||||
| 		Status:          Imported, | 		Status:          Imported, | ||||||
| @@ -689,17 +693,22 @@ func (i *OFXImport) GetInvSellTran(sell *ofxgo.InvSell, curdef *Security, accoun | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	var commission, taxes, fees, load, total, tradingTotal big.Rat | 	var commission, taxes, fees, load, total, tradingTotal big.Rat | ||||||
| 	commission.Set(&sell.Commission.Rat) | 	commission.Abs(&sell.Commission.Rat) | ||||||
| 	taxes.Set(&sell.Taxes.Rat) | 	taxes.Abs(&sell.Taxes.Rat) | ||||||
| 	fees.Set(&sell.Fees.Rat) | 	fees.Abs(&sell.Fees.Rat) | ||||||
| 	load.Set(&sell.Load.Rat) | 	load.Abs(&sell.Load.Rat) | ||||||
| 	total.Set(&sell.Total.Rat) | 	total.Abs(&sell.Total.Rat) | ||||||
|  |  | ||||||
|  | 	commission.Neg(&commission) | ||||||
|  | 	taxes.Neg(&taxes) | ||||||
|  | 	fees.Neg(&fees) | ||||||
|  | 	load.Neg(&load) | ||||||
|  |  | ||||||
| 	tradingTotal.Neg(&total) | 	tradingTotal.Neg(&total) | ||||||
| 	tradingTotal.Sub(&tradingTotal, &commission) | 	tradingTotal.Add(&tradingTotal, &commission) | ||||||
| 	tradingTotal.Sub(&tradingTotal, &taxes) | 	tradingTotal.Add(&tradingTotal, &taxes) | ||||||
| 	tradingTotal.Sub(&tradingTotal, &fees) | 	tradingTotal.Add(&tradingTotal, &fees) | ||||||
| 	tradingTotal.Sub(&tradingTotal, &load) | 	tradingTotal.Add(&tradingTotal, &load) | ||||||
|  |  | ||||||
| 	// Convert amounts to account's currency if Currency is set | 	// Convert amounts to account's currency if Currency is set | ||||||
| 	if ok, _ := sell.Currency.Valid(); ok { | 	if ok, _ := sell.Currency.Valid(); ok { | ||||||
| @@ -781,11 +790,11 @@ func (i *OFXImport) GetInvSellTran(sell *ofxgo.InvSell, curdef *Security, accoun | |||||||
| 	}) | 	}) | ||||||
|  |  | ||||||
| 	var units big.Rat | 	var units big.Rat | ||||||
| 	units.Set(&sell.Units.Rat) | 	units.Abs(&sell.Units.Rat) | ||||||
| 	t.Splits = append(t.Splits, &Split{ | 	t.Splits = append(t.Splits, &Split{ | ||||||
| 		// TODO ReversalFiTID? | 		// TODO ReversalFiTID? | ||||||
| 		Status:          Imported, | 		Status:          Imported, | ||||||
| 		ImportSplitType: SubAccount, | 		ImportSplitType: TradingAccount, | ||||||
| 		AccountId:       -1, | 		AccountId:       -1, | ||||||
| 		SecurityId:      security.SecurityId, | 		SecurityId:      security.SecurityId, | ||||||
| 		RemoteId:        "ofx:" + sell.InvTran.FiTID.String(), | 		RemoteId:        "ofx:" + sell.InvTran.FiTID.String(), | ||||||
| @@ -796,7 +805,7 @@ func (i *OFXImport) GetInvSellTran(sell *ofxgo.InvSell, curdef *Security, accoun | |||||||
| 	t.Splits = append(t.Splits, &Split{ | 	t.Splits = append(t.Splits, &Split{ | ||||||
| 		// TODO ReversalFiTID? | 		// TODO ReversalFiTID? | ||||||
| 		Status:          Imported, | 		Status:          Imported, | ||||||
| 		ImportSplitType: TradingAccount, | 		ImportSplitType: SubAccount, | ||||||
| 		AccountId:       -1, | 		AccountId:       -1, | ||||||
| 		SecurityId:      security.SecurityId, | 		SecurityId:      security.SecurityId, | ||||||
| 		RemoteId:        "ofx:" + sell.InvTran.FiTID.String(), | 		RemoteId:        "ofx:" + sell.InvTran.FiTID.String(), | ||||||
|   | |||||||
							
								
								
									
										229
									
								
								internal/handlers/ofx_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										229
									
								
								internal/handlers/ofx_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,229 @@ | |||||||
|  | package handlers_test | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"github.com/aclindsa/moneygo/internal/handlers" | ||||||
|  | 	"net/http" | ||||||
|  | 	"strconv" | ||||||
|  | 	"testing" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func importOFX(client *http.Client, accountid int64, filename string) error { | ||||||
|  | 	return uploadFile(client, filename, "/v1/accounts/"+strconv.FormatInt(accountid, 10)+"/imports/ofxfile") | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func TestImportOFXChecking(t *testing.T) { | ||||||
|  | 	RunWith(t, &data[0], func(t *testing.T, d *TestData) { | ||||||
|  | 		// Ensure there's only one USD currency | ||||||
|  | 		oldDefault, err := getSecurity(d.clients[0], d.users[0].DefaultCurrency) | ||||||
|  | 		if err != nil { | ||||||
|  | 			t.Fatalf("Error fetching default security: %s\n", err) | ||||||
|  | 		} | ||||||
|  | 		d.users[0].DefaultCurrency = d.securities[0].SecurityId | ||||||
|  | 		if _, err := updateUser(d.clients[0], &d.users[0]); err != nil { | ||||||
|  | 			t.Fatalf("Error updating user: %s\n", err) | ||||||
|  | 		} | ||||||
|  | 		if err := deleteSecurity(d.clients[0], oldDefault); err != nil { | ||||||
|  | 			t.Fatalf("Error removing default security: %s\n", err) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		// Import and ensure it didn't return a nasty error code | ||||||
|  | 		if err = importOFX(d.clients[0], d.accounts[1].AccountId, "handlers_testdata/checking_20171126.ofx"); err != nil { | ||||||
|  | 			t.Fatalf("Error importing OFX: %s\n", err) | ||||||
|  | 		} | ||||||
|  | 		accountBalanceHelper(t, d.clients[0], &d.accounts[1], "2493.19") | ||||||
|  |  | ||||||
|  | 		if err = importOFX(d.clients[0], d.accounts[1].AccountId, "handlers_testdata/checking_20171129.ofx"); err != nil { | ||||||
|  | 			t.Fatalf("Error importing OFX: %s\n", err) | ||||||
|  | 		} | ||||||
|  | 		accountBalanceHelper(t, d.clients[0], &d.accounts[1], "5336.27") | ||||||
|  | 	}) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func TestImportOFXCreditCard(t *testing.T) { | ||||||
|  | 	RunWith(t, &data[0], func(t *testing.T, d *TestData) { | ||||||
|  | 		// Ensure there's only one USD currency | ||||||
|  | 		oldDefault, err := getSecurity(d.clients[0], d.users[0].DefaultCurrency) | ||||||
|  | 		if err != nil { | ||||||
|  | 			t.Fatalf("Error fetching default security: %s\n", err) | ||||||
|  | 		} | ||||||
|  | 		d.users[0].DefaultCurrency = d.securities[0].SecurityId | ||||||
|  | 		if _, err := updateUser(d.clients[0], &d.users[0]); err != nil { | ||||||
|  | 			t.Fatalf("Error updating user: %s\n", err) | ||||||
|  | 		} | ||||||
|  | 		if err := deleteSecurity(d.clients[0], oldDefault); err != nil { | ||||||
|  | 			t.Fatalf("Error removing default security: %s\n", err) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		// Import and ensure it didn't return a nasty error code | ||||||
|  | 		if err = importOFX(d.clients[0], d.accounts[7].AccountId, "handlers_testdata/creditcard.ofx"); err != nil { | ||||||
|  | 			t.Fatalf("Error importing OFX: %s\n", err) | ||||||
|  | 		} | ||||||
|  | 		accountBalanceHelper(t, d.clients[0], &d.accounts[7], "-4.49") | ||||||
|  | 	}) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func findSecurity(client *http.Client, symbol string, tipe handlers.SecurityType) (*handlers.Security, error) { | ||||||
|  | 	securities, err := getSecurities(client) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	for _, security := range *securities.Securities { | ||||||
|  | 		if security.Symbol == symbol && security.Type == tipe { | ||||||
|  | 			return security, nil | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return nil, fmt.Errorf("Unable to find security: \"%s\"", symbol) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func findAccount(client *http.Client, name string, tipe handlers.AccountType, securityid int64) (*handlers.Account, error) { | ||||||
|  | 	accounts, err := getAccounts(client) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	for _, account := range *accounts.Accounts { | ||||||
|  | 		if account.Name == name && account.Type == tipe && account.SecurityId == securityid { | ||||||
|  | 			return &account, nil | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return nil, fmt.Errorf("Unable to find account: \"%s\"", name) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func TestImportOFX401kMutualFunds(t *testing.T) { | ||||||
|  | 	RunWith(t, &data[0], func(t *testing.T, d *TestData) { | ||||||
|  | 		// Ensure there's only one USD currency | ||||||
|  | 		oldDefault, err := getSecurity(d.clients[0], d.users[0].DefaultCurrency) | ||||||
|  | 		if err != nil { | ||||||
|  | 			t.Fatalf("Error fetching default security: %s\n", err) | ||||||
|  | 		} | ||||||
|  | 		d.users[0].DefaultCurrency = d.securities[0].SecurityId | ||||||
|  | 		if _, err := updateUser(d.clients[0], &d.users[0]); err != nil { | ||||||
|  | 			t.Fatalf("Error updating user: %s\n", err) | ||||||
|  | 		} | ||||||
|  | 		if err := deleteSecurity(d.clients[0], oldDefault); err != nil { | ||||||
|  | 			t.Fatalf("Error removing default security: %s\n", err) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		account := &handlers.Account{ | ||||||
|  | 			SecurityId:      d.securities[0].SecurityId, | ||||||
|  | 			UserId:          d.users[0].UserId, | ||||||
|  | 			ParentAccountId: -1, | ||||||
|  | 			Type:            handlers.Investment, | ||||||
|  | 			Name:            "401k", | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		account, err = createAccount(d.clients[0], account) | ||||||
|  | 		if err != nil { | ||||||
|  | 			t.Fatalf("Error creating 401k account: %s\n", err) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		// Import and ensure it didn't return a nasty error code | ||||||
|  | 		if err = importOFX(d.clients[0], account.AccountId, "handlers_testdata/401k_mutualfunds.ofx"); err != nil { | ||||||
|  | 			t.Fatalf("Error importing OFX: %s\n", err) | ||||||
|  | 		} | ||||||
|  | 		accountBalanceHelper(t, d.clients[0], account, "-192.10") | ||||||
|  |  | ||||||
|  | 		// Make sure the security was created and that the trading account has | ||||||
|  | 		// the right value | ||||||
|  | 		security, err := findSecurity(d.clients[0], "VANGUARD TARGET 2045", handlers.Stock) | ||||||
|  | 		if err != nil { | ||||||
|  | 			t.Fatalf("Error finding VANGUARD TARGET 2045 security: %s\n", err) | ||||||
|  | 		} | ||||||
|  | 		tradingaccount, err := findAccount(d.clients[0], "VANGUARD TARGET 2045", handlers.Trading, security.SecurityId) | ||||||
|  | 		if err != nil { | ||||||
|  | 			t.Fatalf("Error finding VANGUARD TARGET 2045 trading account: %s\n", err) | ||||||
|  | 		} | ||||||
|  | 		accountBalanceHelper(t, d.clients[0], tradingaccount, "-3.35400") | ||||||
|  |  | ||||||
|  | 		// Ensure actual holding account was created and in the correct place | ||||||
|  | 		investmentaccount, err := findAccount(d.clients[0], "VANGUARD TARGET 2045", handlers.Investment, security.SecurityId) | ||||||
|  | 		if err != nil { | ||||||
|  | 			t.Fatalf("Error finding VANGUARD TARGET 2045 investment account: %s\n", err) | ||||||
|  | 		} | ||||||
|  | 		accountBalanceHelper(t, d.clients[0], investmentaccount, "3.35400") | ||||||
|  | 		if investmentaccount.ParentAccountId != account.AccountId { | ||||||
|  | 			t.Errorf("Expected imported security account to be child of investment account it's imported into\n") | ||||||
|  | 		} | ||||||
|  | 	}) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func TestImportOFXBrokerage(t *testing.T) { | ||||||
|  | 	RunWith(t, &data[0], func(t *testing.T, d *TestData) { | ||||||
|  | 		// Ensure there's only one USD currency | ||||||
|  | 		oldDefault, err := getSecurity(d.clients[0], d.users[0].DefaultCurrency) | ||||||
|  | 		if err != nil { | ||||||
|  | 			t.Fatalf("Error fetching default security: %s\n", err) | ||||||
|  | 		} | ||||||
|  | 		d.users[0].DefaultCurrency = d.securities[0].SecurityId | ||||||
|  | 		if _, err := updateUser(d.clients[0], &d.users[0]); err != nil { | ||||||
|  | 			t.Fatalf("Error updating user: %s\n", err) | ||||||
|  | 		} | ||||||
|  | 		if err := deleteSecurity(d.clients[0], oldDefault); err != nil { | ||||||
|  | 			t.Fatalf("Error removing default security: %s\n", err) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		// Create the brokerage account | ||||||
|  | 		account := &handlers.Account{ | ||||||
|  | 			SecurityId:      d.securities[0].SecurityId, | ||||||
|  | 			UserId:          d.users[0].UserId, | ||||||
|  | 			ParentAccountId: -1, | ||||||
|  | 			Type:            handlers.Investment, | ||||||
|  | 			Name:            "Personal Brokerage", | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		account, err = createAccount(d.clients[0], account) | ||||||
|  | 		if err != nil { | ||||||
|  | 			t.Fatalf("Error creating 'Personal Brokerage' account: %s\n", err) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		// Import and ensure it didn't return a nasty error code | ||||||
|  | 		if err = importOFX(d.clients[0], account.AccountId, "handlers_testdata/brokerage.ofx"); err != nil { | ||||||
|  | 			t.Fatalf("Error importing OFX: %s\n", err) | ||||||
|  | 		} | ||||||
|  | 		accountBalanceHelper(t, d.clients[0], account, "387.48") | ||||||
|  |  | ||||||
|  | 		// Make sure the USD trading account was created and has  the right | ||||||
|  | 		// value | ||||||
|  | 		usdtrading, err := findAccount(d.clients[0], "USD", handlers.Trading, d.users[0].DefaultCurrency) | ||||||
|  | 		if err != nil { | ||||||
|  | 			t.Fatalf("Error finding USD trading account: %s\n", err) | ||||||
|  | 		} | ||||||
|  | 		accountBalanceHelper(t, d.clients[0], usdtrading, "619.96") | ||||||
|  |  | ||||||
|  | 		// Check investment/trading balances for all securities traded | ||||||
|  | 		checks := []struct { | ||||||
|  | 			Ticker         string | ||||||
|  | 			Name           string | ||||||
|  | 			Balance        string | ||||||
|  | 			TradingBalance string | ||||||
|  | 		}{ | ||||||
|  | 			{"VBMFX", "Vanguard Total Bond Market Index Fund Investor Shares", "37.70000", "-37.70000"}, | ||||||
|  | 			{"921909768", "VANGUARD TOTAL INTL STOCK INDE", "5.00000", "-5.00000"}, | ||||||
|  | 			{"ATO", "ATMOS ENERGY CORP", "0.08600", "-0.08600"}, | ||||||
|  | 			{"VMFXX", "Vanguard Federal Money Market Fund", "-21.57000", "21.57000"}, | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		for _, check := range checks { | ||||||
|  | 			security, err := findSecurity(d.clients[0], check.Ticker, handlers.Stock) | ||||||
|  | 			if err != nil { | ||||||
|  | 				t.Fatalf("Error finding security: %s\n", err) | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			account, err := findAccount(d.clients[0], check.Name, handlers.Investment, security.SecurityId) | ||||||
|  | 			if err != nil { | ||||||
|  | 				t.Fatalf("Error finding trading account: %s\n", err) | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			accountBalanceHelper(t, d.clients[0], account, check.Balance) | ||||||
|  |  | ||||||
|  | 			tradingaccount, err := findAccount(d.clients[0], check.Name, handlers.Trading, security.SecurityId) | ||||||
|  | 			if err != nil { | ||||||
|  | 				t.Fatalf("Error finding trading account: %s\n", err) | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			accountBalanceHelper(t, d.clients[0], tradingaccount, check.TradingBalance) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		// TODO check reinvestment/income to make sure they're registered as income? | ||||||
|  | 	}) | ||||||
|  | } | ||||||
| @@ -257,7 +257,7 @@ var data = []TestData{ | |||||||
| 				UserId:          0, | 				UserId:          0, | ||||||
| 				SecurityId:      0, | 				SecurityId:      0, | ||||||
| 				ParentAccountId: 0, | 				ParentAccountId: 0, | ||||||
| 				Type:            handlers.Asset, | 				Type:            handlers.Bank, | ||||||
| 				Name:            "Credit Union Checking", | 				Name:            "Credit Union Checking", | ||||||
| 			}, | 			}, | ||||||
| 			{ | 			{ | ||||||
| @@ -295,6 +295,13 @@ var data = []TestData{ | |||||||
| 				Type:            handlers.Expense, | 				Type:            handlers.Expense, | ||||||
| 				Name:            "Expenses", | 				Name:            "Expenses", | ||||||
| 			}, | 			}, | ||||||
|  | 			{ | ||||||
|  | 				UserId:          0, | ||||||
|  | 				SecurityId:      0, | ||||||
|  | 				ParentAccountId: -1, | ||||||
|  | 				Type:            handlers.Liability, | ||||||
|  | 				Name:            "Credit Card", | ||||||
|  | 			}, | ||||||
| 		}, | 		}, | ||||||
| 		transactions: []handlers.Transaction{ | 		transactions: []handlers.Transaction{ | ||||||
| 			{ | 			{ | ||||||
| @@ -462,6 +469,10 @@ end`, | |||||||
| 							}, | 							}, | ||||||
| 						}, | 						}, | ||||||
| 					}, | 					}, | ||||||
|  | 					"Credit Card": { | ||||||
|  | 						Values: []float64{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, | ||||||
|  | 						Series: map[string]*handlers.Series{}, | ||||||
|  | 					}, | ||||||
| 				}, | 				}, | ||||||
| 			}, | 			}, | ||||||
| 		}, | 		}, | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user