Clarify use of Currency vs. OrigCurrency

This commit is contained in:
Aaron Lindsay 2017-04-19 21:23:37 -04:00
parent bc541d881d
commit 4cb0eb4f85
6 changed files with 55 additions and 67 deletions

46
bank.go
View File

@ -117,15 +117,17 @@ type Transaction struct {
SIC Int `xml:"SIC,omitempty"` // Standard Industrial Code
PayeeID String `xml:"PAYEEID,omitempty"`
// Note: Servers should provide NAME or PAYEE, but not both
Name String `xml:"NAME,omitempty"`
Payee *Payee `xml:"PAYEE,omitempty"`
ExtdName String `xml:"EXTDNAME,omitempty"` // Extended name of payee or transaction description
BankAcctTo *BankAcct `xml:"BANKACCTTO,omitempty"` // If the transfer was to a bank account we have the account information for
CCAcctTo *CCAcct `xml:"CCACCTTO,omitempty"` // If the transfer was to a credit card account we have the account information for
Memo String `xml:"MEMO,omitempty"` // Extra information (not in NAME)
ImageData []ImageData `xml:"IMAGEDATA,omitempty"`
Currency Currency `xml:"CURRENCY,omitempty"` // If different from CURDEF in STMTTRS
OrigCurrency Currency `xml:"ORIGCURRENCY,omitempty"` // If different from CURDEF in STMTTRS
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.)
}
@ -202,18 +204,20 @@ func (l TransactionList) Valid(version ofxVersion) (bool, error) {
// 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"`
Currency Currency `xml:"CURRENCY,omitempty"` // If different from CURDEF in STMTTRS
OrigCurrency Currency `xml:"ORIGCURRENCY,omitempty"` // If different from CURDEF in STMTTRS
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

View File

@ -79,8 +79,6 @@ func printTransaction(defCurrency ofxgo.CurrSymbol, tran *ofxgo.Transaction) {
currency := defCurrency
if ok, _ := tran.Currency.Valid(); ok {
currency = tran.Currency.CurSym
} else if ok, _ := tran.OrigCurrency.Valid(); ok {
currency = tran.OrigCurrency.CurSym
}
var name string

View File

@ -62,8 +62,6 @@ func ccTransactions() {
currency := stmt.CurDef
if ok, _ := tran.Currency.Valid(); ok {
currency = tran.Currency.CurSym
} else if ok, _ := tran.OrigCurrency.Valid(); ok {
currency = tran.OrigCurrency.CurSym
}
var name string

View File

@ -92,9 +92,7 @@ func invTransactions() {
case ofxgo.Income:
printInvTran(&tran.InvTran)
currency := stmt.CurDef
if tran.Currency != nil {
currency = tran.Currency.CurSym
} else if tran.OrigCurrency != nil {
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)
@ -102,9 +100,7 @@ func invTransactions() {
case ofxgo.InvExpense:
printInvTran(&tran.InvTran)
currency := stmt.CurDef
if tran.Currency != nil {
currency = tran.Currency.CurSym
} else if tran.OrigCurrency != nil {
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)
@ -119,18 +115,14 @@ func invTransactions() {
case ofxgo.MarginInterest:
printInvTran(&tran.InvTran)
currency := stmt.CurDef
if tran.Currency != nil {
currency = tran.Currency.CurSym
} else if tran.OrigCurrency != nil {
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 tran.Currency != nil {
currency = tran.Currency.CurSym
} else if tran.OrigCurrency != nil {
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)
@ -138,9 +130,7 @@ func invTransactions() {
case ofxgo.RetOfCap:
printInvTran(&tran.InvTran)
currency := stmt.CurDef
if tran.Currency != nil {
currency = tran.Currency.CurSym
} else if tran.OrigCurrency != nil {
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)
@ -158,9 +148,7 @@ func invTransactions() {
case ofxgo.Split:
printInvTran(&tran.InvTran)
currency := stmt.CurDef
if tran.Currency != nil {
currency = tran.Currency.CurSym
} else if tran.OrigCurrency != nil {
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)
@ -181,9 +169,7 @@ func printInvTran(it *ofxgo.InvTran) {
func printInvBuy(defCurrency ofxgo.CurrSymbol, ib *ofxgo.InvBuy) {
printInvTran(&ib.InvTran)
currency := defCurrency
if ok, _ := ib.Currency.CurSym.Valid(); ok {
currency = ib.Currency.CurSym
} else if ok, _ := ib.OrigCurrency.CurSym.Valid(); ok {
if ok, _ := ib.Currency.Valid(); ok {
currency = ib.Currency.CurSym
}
@ -194,9 +180,7 @@ func printInvBuy(defCurrency ofxgo.CurrSymbol, ib *ofxgo.InvBuy) {
func printInvSell(defCurrency ofxgo.CurrSymbol, is *ofxgo.InvSell) {
printInvTran(&is.InvTran)
currency := defCurrency
if ok, _ := is.Currency.CurSym.Valid(); ok {
currency = is.Currency.CurSym
} else if ok, _ := is.OrigCurrency.CurSym.Valid(); ok {
if ok, _ := is.Currency.Valid(); ok {
currency = is.Currency.CurSym
}

View File

@ -310,10 +310,14 @@ type InvAcct struct {
AcctID String `xml:"ACCTID"`
}
// Currency represents one ISO-4217 currency
// 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 <CURDEF> currency to <CURSYM> currency
CurRate Amount `xml:"CURRATE"` // Ratio of statement's currency (CURDEF) to transaction currency (CURSYM)
CurSym CurrSymbol `xml:"CURSYM"` // ISO-4217 3-character currency identifier
}

View File

@ -75,8 +75,8 @@ type InvBuy struct {
Fees Amount `xml:"FEES,omitempty"`
Load Amount `xml:"LOAD,omitempty"`
Total Amount `xml:"TOTAL"` // Transaction total. Buys, sells, etc.:((quan. * (price +/- markup/markdown)) +/-(commission + fees + load + taxes + penalty + withholding + statewithholding)). Distributions, interest, margin interest, misc. expense, etc.: amount. Return of cap: cost basis
Currency *Currency `xml:"CURRENCY,omitempty"` // Overriding currency for UNITPRICE
OrigCurrency *Currency `xml:"ORIGCURRENCY,omitempty"` // Overriding currency for UNITPRICE
Currency Currency `xml:"CURRENCY,omitempty"` // Represents the currency this transaction is in (instead of CURDEF in INVSTMTRS) if Valid()
OrigCurrency Currency `xml:"ORIGCURRENCY,omitempty"` // Represents the currency this transaction was converted to INVSTMTRS' CURDEF from if Valid
SubAcctSec subAcctType `xml:"SUBACCTSEC"` // Sub-account type for this security. One of CASH, MARGIN, SHORT, OTHER
SubAcctFund subAcctType `xml:"SUBACCTFUND"` // Where did the money for the transaction come from or go to? CASH, MARGIN, SHORT, OTHER
@ -107,8 +107,8 @@ type InvSell struct {
TaxExempt Boolean `xml:"TAXEXEMPT,omitempty"` // Tax-exempt transaction
Total Amount `xml:"TOTAL"` // Transaction total. Buys, sells, etc.:((quan. * (price +/- markup/markdown)) +/-(commission + fees + load + taxes + penalty + withholding + statewithholding)). Distributions, interest, margin interest, misc. expense, etc.: amount. Return of cap: cost basis
Gain Amount `xml:"GAIN,omitempty"` // Total gain
Currency *Currency `xml:"CURRENCY,omitempty"` // Overriding currency for UNITPRICE
OrigCurrency *Currency `xml:"ORIGCURRENCY,omitempty"` // Overriding currency for UNITPRICE
Currency Currency `xml:"CURRENCY,omitempty"` // Represents the currency this transaction is in (instead of CURDEF in INVSTMTRS) if Valid()
OrigCurrency Currency `xml:"ORIGCURRENCY,omitempty"` // Represents the currency this transaction was converted to INVSTMTRS' CURDEF from if Valid
SubAcctSec subAcctType `xml:"SUBACCTSEC"` // Sub-account type for this security. One of CASH, MARGIN, SHORT, OTHER
SubAcctFund subAcctType `xml:"SUBACCTFUND"` // Where did the money for the transaction come from or go to? CASH, MARGIN, SHORT, OTHER
@ -211,8 +211,8 @@ type Income struct {
SubAcctFund subAcctType `xml:"SUBACCTFUND"` // Where did the money for the transaction come from or go to? CASH, MARGIN, SHORT, OTHER
TaxExempt Boolean `xml:"TAXEXEMPT,omitempty"` // Tax-exempt transaction
Witholding Amount `xml:"WITHHOLDING,omitempty"` // Federal tax witholdings
Currency *Currency `xml:"CURRENCY,omitempty"` // Overriding currency for UNITPRICE
OrigCurrency *Currency `xml:"ORIGCURRENCY,omitempty"` // Overriding currency for UNITPRICE
Currency Currency `xml:"CURRENCY,omitempty"` // Represents the currency this transaction is in (instead of CURDEF in INVSTMTRS) if Valid()
OrigCurrency Currency `xml:"ORIGCURRENCY,omitempty"` // Represents the currency this transaction was converted to INVSTMTRS' CURDEF from if Valid
Inv401kSource inv401kSource `xml:"INV401KSOURCE,omitempty"` // Source of money for this transaction. One of PRETAX, AFTERTAX, MATCH, PROFITSHARING, ROLLOVER, OTHERVEST, OTHERNONVEST for 401(k) accounts. Default if not present is OTHERNONVEST. The following cash source types are subject to vesting: MATCH, PROFITSHARING, and OTHERVEST
}
@ -230,8 +230,8 @@ type InvExpense struct {
Total Amount `xml:"TOTAL"`
SubAcctSec subAcctType `xml:"SUBACCTSEC"` // Sub-account type for this security. One of CASH, MARGIN, SHORT, OTHER
SubAcctFund subAcctType `xml:"SUBACCTFUND"` // Where did the money for the transaction come from or go to? CASH, MARGIN, SHORT, OTHER
Currency *Currency `xml:"CURRENCY,omitempty"` // Overriding currency for UNITPRICE
OrigCurrency *Currency `xml:"ORIGCURRENCY,omitempty"` // Overriding currency for UNITPRICE
Currency Currency `xml:"CURRENCY,omitempty"` // Represents the currency this transaction is in (instead of CURDEF in INVSTMTRS) if Valid()
OrigCurrency Currency `xml:"ORIGCURRENCY,omitempty"` // Represents the currency this transaction was converted to INVSTMTRS' CURDEF from if Valid
Inv401kSource inv401kSource `xml:"INV401KSOURCE,omitempty"` // Source of money for this transaction. One of PRETAX, AFTERTAX, MATCH, PROFITSHARING, ROLLOVER, OTHERVEST, OTHERNONVEST for 401(k) accounts. Default if not present is OTHERNONVEST. The following cash source types are subject to vesting: MATCH, PROFITSHARING, and OTHERVEST
}
@ -277,8 +277,8 @@ type MarginInterest struct {
InvTran InvTran `xml:"INVTRAN"`
Total Amount `xml:"TOTAL"`
SubAcctFund subAcctType `xml:"SUBACCTFUND"` // Where did the money for the transaction come from or go to? CASH, MARGIN, SHORT, OTHER
Currency *Currency `xml:"CURRENCY,omitempty"` // Overriding currency for UNITPRICE
OrigCurrency *Currency `xml:"ORIGCURRENCY,omitempty"` // Overriding currency for UNITPRICE
Currency Currency `xml:"CURRENCY,omitempty"` // Represents the currency this transaction is in (instead of CURDEF in INVSTMTRS) if Valid()
OrigCurrency Currency `xml:"ORIGCURRENCY,omitempty"` // Represents the currency this transaction was converted to INVSTMTRS' CURDEF from if Valid
}
// TransactionType returns a string representation of this transaction's type
@ -303,8 +303,8 @@ type Reinvest struct {
Fees Amount `xml:"FEES,omitempty"`
Load Amount `xml:"LOAD,omitempty"`
TaxExempt Boolean `xml:"TAXEXEMPT,omitempty"` // Tax-exempt transaction
Currency *Currency `xml:"CURRENCY,omitempty"` // Overriding currency for UNITPRICE
OrigCurrency *Currency `xml:"ORIGCURRENCY,omitempty"` // Overriding currency for UNITPRICE
Currency Currency `xml:"CURRENCY,omitempty"` // Represents the currency this transaction is in (instead of CURDEF in INVSTMTRS) if Valid()
OrigCurrency Currency `xml:"ORIGCURRENCY,omitempty"` // Represents the currency this transaction was converted to INVSTMTRS' CURDEF from if Valid
Inv401kSource inv401kSource `xml:"INV401KSOURCE,omitempty"` // Source of money for this transaction. One of PRETAX, AFTERTAX, MATCH, PROFITSHARING, ROLLOVER, OTHERVEST, OTHERNONVEST for 401(k) accounts. Default if not present is OTHERNONVEST. The following cash source types are subject to vesting: MATCH, PROFITSHARING, and OTHERVEST
}
@ -322,8 +322,8 @@ type RetOfCap struct {
Total Amount `xml:"TOTAL"`
SubAcctSec subAcctType `xml:"SUBACCTSEC"` // Sub-account type for this security. One of CASH, MARGIN, SHORT, OTHER
SubAcctFund subAcctType `xml:"SUBACCTFUND"` // Where did the money for the transaction come from or go to? CASH, MARGIN, SHORT, OTHER
Currency *Currency `xml:"CURRENCY,omitempty"` // Overriding currency for UNITPRICE
OrigCurrency *Currency `xml:"ORIGCURRENCY,omitempty"` // Overriding currency for UNITPRICE
Currency Currency `xml:"CURRENCY,omitempty"` // Represents the currency this transaction is in (instead of CURDEF in INVSTMTRS) if Valid()
OrigCurrency Currency `xml:"ORIGCURRENCY,omitempty"` // Represents the currency this transaction was converted to INVSTMTRS' CURDEF from if Valid
Inv401kSource inv401kSource `xml:"INV401KSOURCE,omitempty"` // Source of money for this transaction. One of PRETAX, AFTERTAX, MATCH, PROFITSHARING, ROLLOVER, OTHERVEST, OTHERNONVEST for 401(k) accounts. Default if not present is OTHERNONVEST. The following cash source types are subject to vesting: MATCH, PROFITSHARING, and OTHERVEST
}
@ -412,8 +412,8 @@ type Split struct {
NewUnits Amount `xml:"NEWUNITS"` // number of shares after the split
Numerator Int `xml:"NUMERATOR"` // split ratio numerator
Denominator Int `xml:"DENOMINATOR"` // split ratio denominator
Currency *Currency `xml:"CURRENCY,omitempty"` // Overriding currency for UNITPRICE
OrigCurrency *Currency `xml:"ORIGCURRENCY,omitempty"` // Overriding currency for UNITPRICE
Currency Currency `xml:"CURRENCY,omitempty"` // Represents the currency this transaction is in (instead of CURDEF in INVSTMTRS) if Valid()
OrigCurrency Currency `xml:"ORIGCURRENCY,omitempty"` // Represents the currency this transaction was converted to INVSTMTRS' CURDEF from if Valid
FracCash Amount `xml:"FRACCASH,omitempty"` // cash for fractional units
SubAcctFund subAcctType `xml:"SUBACCTFUND,omitempty"` // Where did the money for the transaction come from or go to? CASH, MARGIN, SHORT, OTHER
Inv401kSource inv401kSource `xml:"INV401KSOURCE,omitempty"` // Source of money for this transaction. One of PRETAX, AFTERTAX, MATCH, PROFITSHARING, ROLLOVER, OTHERVEST, OTHERNONVEST for 401(k) accounts. Default if not present is OTHERNONVEST. The following cash source types are subject to vesting: MATCH, PROFITSHARING, and OTHERVEST