From d31ac10d085bee63dd981cbe15314541c77fe6ba Mon Sep 17 00:00:00 2001 From: David Bartley Date: Sat, 6 Apr 2024 23:20:37 -0700 Subject: [PATCH] Add `InvTransaction()` method to `InvTransaction` interface. --- invstmt.go | 81 +++++++++++++++++++++++++++++++++++++++++++++++++ invstmt_test.go | 40 +++++++++++++++++++++++- 2 files changed, 120 insertions(+), 1 deletion(-) diff --git a/invstmt.go b/invstmt.go index a913f7f..3e4e134 100644 --- a/invstmt.go +++ b/invstmt.go @@ -131,6 +131,10 @@ func (t BuyDebt) TransactionType() string { return "BUYDEBT" } +func (t BuyDebt) InvTransaction() InvTran { + return t.InvBuy.InvTran +} + // BuyMF represents a transaction purchasing a mutual fund type BuyMF struct { XMLName xml.Name `xml:"BUYMF"` @@ -144,6 +148,10 @@ func (t BuyMF) TransactionType() string { return "BUYMF" } +func (t BuyMF) InvTransaction() InvTran { + return t.InvBuy.InvTran +} + // BuyOpt represents a transaction purchasing an option type BuyOpt struct { XMLName xml.Name `xml:"BUYOPT"` @@ -157,6 +165,10 @@ func (t BuyOpt) TransactionType() string { return "BUYOPT" } +func (t BuyOpt) InvTransaction() InvTran { + return t.InvBuy.InvTran +} + // BuyOther represents a transaction purchasing a type of security not covered // by the other Buy* structs type BuyOther struct { @@ -169,6 +181,10 @@ func (t BuyOther) TransactionType() string { return "BUYOTHER" } +func (t BuyOther) InvTransaction() InvTran { + return t.InvBuy.InvTran +} + // BuyStock represents a transaction purchasing stock type BuyStock struct { XMLName xml.Name `xml:"BUYSTOCK"` @@ -181,6 +197,10 @@ func (t BuyStock) TransactionType() string { return "BUYSTOCK" } +func (t BuyStock) InvTransaction() InvTran { + return t.InvBuy.InvTran +} + // ClosureOpt represents a transaction closing a position for an option type ClosureOpt struct { XMLName xml.Name `xml:"CLOSUREOPT"` @@ -199,6 +219,10 @@ func (t ClosureOpt) TransactionType() string { return "CLOSUREOPT" } +func (t ClosureOpt) InvTransaction() InvTran { + return t.InvTran +} + // Income represents a transaction where investment income is being realized as // cash into the investment account type Income struct { @@ -221,6 +245,10 @@ func (t Income) TransactionType() string { return "INCOME" } +func (t Income) InvTransaction() InvTran { + return t.InvTran +} + // InvExpense represents a transaction realizing an expense associated with an // investment type InvExpense struct { @@ -240,6 +268,10 @@ func (t InvExpense) TransactionType() string { return "INVEXPENSE" } +func (t InvExpense) InvTransaction() InvTran { + return t.InvTran +} + // JrnlFund represents a transaction journaling cash holdings between // sub-accounts within the same investment account type JrnlFund struct { @@ -255,6 +287,10 @@ func (t JrnlFund) TransactionType() string { return "JRNLFUND" } +func (t JrnlFund) InvTransaction() InvTran { + return t.InvTran +} + // JrnlSec represents a transaction journaling security holdings between // sub-accounts within the same investment account type JrnlSec struct { @@ -271,6 +307,10 @@ func (t JrnlSec) TransactionType() string { return "JRNLSEC" } +func (t JrnlSec) InvTransaction() InvTran { + return t.InvTran +} + // MarginInterest represents a transaction realizing a margin interest expense type MarginInterest struct { XMLName xml.Name `xml:"MARGININTEREST"` @@ -286,6 +326,10 @@ func (t MarginInterest) TransactionType() string { return "MARGININTEREST" } +func (t MarginInterest) InvTransaction() InvTran { + return t.InvTran +} + // Reinvest is a single transaction that contains both income and an investment // transaction. If servers can’t track this as a single transaction they should // return an Income transaction and an InvTran. @@ -313,6 +357,10 @@ func (t Reinvest) TransactionType() string { return "REINVEST" } +func (t Reinvest) InvTransaction() InvTran { + return t.InvTran +} + // RetOfCap represents a transaction where capital is being returned to the // account holder type RetOfCap struct { @@ -332,6 +380,10 @@ func (t RetOfCap) TransactionType() string { return "RETOFCAP" } +func (t RetOfCap) InvTransaction() InvTran { + return t.InvTran +} + // SellDebt represents the sale of a debt security. Used when debt is sold, // called, or reaches maturity. type SellDebt struct { @@ -346,6 +398,10 @@ func (t SellDebt) TransactionType() string { return "SELLDEBT" } +func (t SellDebt) InvTransaction() InvTran { + return t.InvSell.InvTran +} + // SellMF represents a transaction selling a mutual fund type SellMF struct { XMLName xml.Name `xml:"SELLMF"` @@ -360,6 +416,10 @@ func (t SellMF) TransactionType() string { return "SELLMF" } +func (t SellMF) InvTransaction() InvTran { + return t.InvSell.InvTran +} + // SellOpt represents a transaction selling an option. Depending on the value // of OptSellType, can be used to sell a previously bought option or write a // new option. @@ -378,6 +438,10 @@ func (t SellOpt) TransactionType() string { return "SELLOPT" } +func (t SellOpt) InvTransaction() InvTran { + return t.InvSell.InvTran +} + // SellOther represents a transaction selling a security type not covered by // the other Sell* structs type SellOther struct { @@ -390,6 +454,10 @@ func (t SellOther) TransactionType() string { return "SELLOTHER" } +func (t SellOther) InvTransaction() InvTran { + return t.InvSell.InvTran +} + // SellStock represents a transaction selling stock type SellStock struct { XMLName xml.Name `xml:"SELLSTOCK"` @@ -402,6 +470,10 @@ func (t SellStock) TransactionType() string { return "SELLSTOCK" } +func (t SellStock) InvTransaction() InvTran { + return t.InvSell.InvTran +} + // Split represents a stock or mutual fund split type Split struct { XMLName xml.Name `xml:"SPLIT"` @@ -424,6 +496,10 @@ func (t Split) TransactionType() string { return "SPLIT" } +func (t Split) InvTransaction() InvTran { + return t.InvTran +} + // Transfer represents the transfer of securities into or out of an account type Transfer struct { XMLName xml.Name `xml:"TRANSFER"` @@ -445,10 +521,15 @@ func (t Transfer) TransactionType() string { return "TRANSFER" } +func (t Transfer) InvTransaction() InvTran { + return t.InvTran +} + // InvTransaction is a generic interface met by all investment transactions // (Buy*, Sell*, & co.) type InvTransaction interface { TransactionType() string + InvTransaction() InvTran } // InvBankTransaction is a banking transaction performed in an investment diff --git a/invstmt_test.go b/invstmt_test.go index a4f1027..768c8a9 100644 --- a/invstmt_test.go +++ b/invstmt_test.go @@ -1,11 +1,12 @@ package ofxgo import ( - "github.com/aclindsa/xml" "reflect" "strings" "testing" "time" + + "github.com/aclindsa/xml" ) func TestMarshalInvStatementRequest(t *testing.T) { @@ -1910,3 +1911,40 @@ func TestInvPosition(t *testing.T) { }) } } + +func TestInvTransaction(t *testing.T) { + invTran := InvTran{ + Memo: "stuff", + } + tests := []InvTransaction{ + BuyDebt{InvBuy: InvBuy{InvTran: invTran}}, + BuyMF{InvBuy: InvBuy{InvTran: invTran}}, + BuyOpt{InvBuy: InvBuy{InvTran: invTran}}, + BuyOther{InvBuy: InvBuy{InvTran: invTran}}, + BuyStock{InvBuy: InvBuy{InvTran: invTran}}, + ClosureOpt{InvTran: invTran}, + Income{InvTran: invTran}, + InvExpense{InvTran: invTran}, + JrnlFund{InvTran: invTran}, + JrnlSec{InvTran: invTran}, + MarginInterest{InvTran: invTran}, + Reinvest{InvTran: invTran}, + RetOfCap{InvTran: invTran}, + SellDebt{InvSell: InvSell{InvTran: invTran}}, + SellMF{InvSell: InvSell{InvTran: invTran}}, + SellOpt{InvSell: InvSell{InvTran: invTran}}, + SellOther{InvSell: InvSell{InvTran: invTran}}, + SellStock{InvSell: InvSell{InvTran: invTran}}, + Split{InvTran: invTran}, + Transfer{InvTran: invTran}, + } + + for _, tc := range tests { + t.Run(tc.TransactionType(), func(t *testing.T) { + tran := tc.InvTransaction() + if tran.Memo != invTran.Memo { + t.Errorf("got %v, want %v", tran, invTran) + } + }) + } +}