Add `InvTransaction()` method to `InvTransaction` interface.

This commit is contained in:
David Bartley 2024-04-06 23:20:37 -07:00 committed by Aaron Lindsay
parent 4f2c5582d1
commit d31ac10d08
2 changed files with 120 additions and 1 deletions

View File

@ -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 cant 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

View File

@ -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)
}
})
}
}