mirror of
https://github.com/aclindsa/moneygo.git
synced 2025-06-14 13:58:37 -04:00
Store currency/security values/prices using big.Rat natively
This adds 'shadow' types used only by the store/db internal package whch handle converting these types to their DB-equivalent values. This change should allow reports to be generated significantly faster since it allows a large portion of the computation to be shifted to the database engines.
This commit is contained in:
@ -202,6 +202,19 @@ func uploadFile(client *http.Client, filename, urlsuffix string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewAmount(amt string) models.Amount {
|
||||
var a models.Amount
|
||||
if _, ok := a.SetString(amt); !ok {
|
||||
panic("Unable to call Amount.SetString()")
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
func amountsMatch(a models.Amount, amt string) bool {
|
||||
cmp := NewAmount(amt)
|
||||
return a.Cmp(&cmp.Rat) == 0
|
||||
}
|
||||
|
||||
func accountBalanceHelper(t *testing.T, client *http.Client, account *models.Account, balance string) {
|
||||
t.Helper()
|
||||
transactions, err := getAccountTransactions(client, account.AccountId, 0, 0, "")
|
||||
@ -209,7 +222,7 @@ func accountBalanceHelper(t *testing.T, client *http.Client, account *models.Acc
|
||||
t.Fatalf("Couldn't fetch account transactions for '%s': %s\n", account.Name, err)
|
||||
}
|
||||
|
||||
if transactions.EndingBalance != balance {
|
||||
if !amountsMatch(transactions.EndingBalance, balance) {
|
||||
t.Errorf("Expected ending balance for '%s' to be '%s', but found %s\n", account.Name, balance, transactions.EndingBalance)
|
||||
}
|
||||
}
|
||||
|
@ -114,11 +114,11 @@ func TestImportGnucash(t *testing.T) {
|
||||
}
|
||||
var p1787, p2894, p3170 bool
|
||||
for _, price := range *prices.Prices {
|
||||
if price.CurrencyId == d.securities[0].SecurityId && price.Value == "17.87" {
|
||||
if price.CurrencyId == d.securities[0].SecurityId && amountsMatch(price.Value, "17.87") {
|
||||
p1787 = true
|
||||
} else if price.CurrencyId == d.securities[0].SecurityId && price.Value == "28.94" {
|
||||
} else if price.CurrencyId == d.securities[0].SecurityId && amountsMatch(price.Value, "28.94") {
|
||||
p2894 = true
|
||||
} else if price.CurrencyId == d.securities[0].SecurityId && price.Value == "31.70" {
|
||||
} else if price.CurrencyId == d.securities[0].SecurityId && amountsMatch(price.Value, "31.70") {
|
||||
p3170 = true
|
||||
}
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ func TestCreatePrice(t *testing.T) {
|
||||
if !p.Date.Equal(orig.Date) {
|
||||
t.Errorf("Date doesn't match")
|
||||
}
|
||||
if p.Value != orig.Value {
|
||||
if p.Value.Cmp(&orig.Value.Rat) != 0 {
|
||||
t.Errorf("Value doesn't match")
|
||||
}
|
||||
if p.RemoteId != orig.RemoteId {
|
||||
@ -98,7 +98,7 @@ func TestGetPrice(t *testing.T) {
|
||||
if !p.Date.Equal(orig.Date) {
|
||||
t.Errorf("Date doesn't match")
|
||||
}
|
||||
if p.Value != orig.Value {
|
||||
if p.Value.Cmp(&orig.Value.Rat) != 0 {
|
||||
t.Errorf("Value doesn't match")
|
||||
}
|
||||
if p.RemoteId != orig.RemoteId {
|
||||
@ -132,7 +132,7 @@ func TestGetPrices(t *testing.T) {
|
||||
|
||||
found := false
|
||||
for _, p := range *pl.Prices {
|
||||
if p.SecurityId == d.securities[orig.SecurityId].SecurityId && p.CurrencyId == d.securities[orig.CurrencyId].SecurityId && p.Date.Equal(orig.Date) && p.Value == orig.Value && p.RemoteId == orig.RemoteId {
|
||||
if p.SecurityId == d.securities[orig.SecurityId].SecurityId && p.CurrencyId == d.securities[orig.CurrencyId].SecurityId && p.Date.Equal(orig.Date) && p.Value.Cmp(&orig.Value.Rat) == 0 && p.RemoteId == orig.RemoteId {
|
||||
if _, ok := foundIds[p.PriceId]; ok {
|
||||
continue
|
||||
}
|
||||
@ -146,7 +146,11 @@ func TestGetPrices(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
if numprices != len(*pl.Prices) {
|
||||
if pl.Prices == nil {
|
||||
if numprices != 0 {
|
||||
t.Fatalf("Expected %d prices, received 0", numprices)
|
||||
}
|
||||
} else if numprices != len(*pl.Prices) {
|
||||
t.Fatalf("Expected %d prices, received %d", numprices, len(*pl.Prices))
|
||||
}
|
||||
}
|
||||
@ -162,7 +166,7 @@ func TestUpdatePrice(t *testing.T) {
|
||||
tmp := curr.SecurityId
|
||||
curr.SecurityId = curr.CurrencyId
|
||||
curr.CurrencyId = tmp
|
||||
curr.Value = "5.55"
|
||||
curr.Value = NewAmount("5.55")
|
||||
curr.Date = time.Date(2019, time.June, 5, 12, 5, 6, 7, time.UTC)
|
||||
curr.RemoteId = "something"
|
||||
|
||||
@ -181,7 +185,7 @@ func TestUpdatePrice(t *testing.T) {
|
||||
if !p.Date.Equal(curr.Date) {
|
||||
t.Errorf("Date doesn't match")
|
||||
}
|
||||
if p.Value != curr.Value {
|
||||
if p.Value.Cmp(&curr.Value.Rat) != 0 {
|
||||
t.Errorf("Value doesn't match")
|
||||
}
|
||||
if p.RemoteId != curr.RemoteId {
|
||||
|
@ -213,35 +213,35 @@ var data = []TestData{
|
||||
SecurityId: 1,
|
||||
CurrencyId: 0,
|
||||
Date: time.Date(2017, time.January, 2, 21, 0, 0, 0, time.UTC),
|
||||
Value: "225.24",
|
||||
Value: NewAmount("225.24"),
|
||||
RemoteId: "12387-129831-1238",
|
||||
},
|
||||
{
|
||||
SecurityId: 1,
|
||||
CurrencyId: 0,
|
||||
Date: time.Date(2017, time.January, 3, 21, 0, 0, 0, time.UTC),
|
||||
Value: "226.58",
|
||||
Value: NewAmount("226.58"),
|
||||
RemoteId: "12387-129831-1239",
|
||||
},
|
||||
{
|
||||
SecurityId: 1,
|
||||
CurrencyId: 0,
|
||||
Date: time.Date(2017, time.January, 4, 21, 0, 0, 0, time.UTC),
|
||||
Value: "226.40",
|
||||
Value: NewAmount("226.40"),
|
||||
RemoteId: "12387-129831-1240",
|
||||
},
|
||||
{
|
||||
SecurityId: 1,
|
||||
CurrencyId: 0,
|
||||
Date: time.Date(2017, time.January, 5, 21, 0, 0, 0, time.UTC),
|
||||
Value: "227.21",
|
||||
Value: NewAmount("227.21"),
|
||||
RemoteId: "12387-129831-1241",
|
||||
},
|
||||
{
|
||||
SecurityId: 0,
|
||||
CurrencyId: 3,
|
||||
Date: time.Date(2017, time.November, 16, 18, 49, 53, 0, time.UTC),
|
||||
Value: "0.85",
|
||||
Value: NewAmount("0.85"),
|
||||
RemoteId: "USDEUR819298714",
|
||||
},
|
||||
},
|
||||
@ -313,13 +313,13 @@ var data = []TestData{
|
||||
Status: models.Reconciled,
|
||||
AccountId: 1,
|
||||
SecurityId: -1,
|
||||
Amount: "-5.6",
|
||||
Amount: NewAmount("-5.6"),
|
||||
},
|
||||
{
|
||||
Status: models.Reconciled,
|
||||
AccountId: 3,
|
||||
SecurityId: -1,
|
||||
Amount: "5.6",
|
||||
Amount: NewAmount("5.6"),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -332,13 +332,13 @@ var data = []TestData{
|
||||
Status: models.Reconciled,
|
||||
AccountId: 1,
|
||||
SecurityId: -1,
|
||||
Amount: "-81.59",
|
||||
Amount: NewAmount("-81.59"),
|
||||
},
|
||||
{
|
||||
Status: models.Reconciled,
|
||||
AccountId: 3,
|
||||
SecurityId: -1,
|
||||
Amount: "81.59",
|
||||
Amount: NewAmount("81.59"),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -351,13 +351,13 @@ var data = []TestData{
|
||||
Status: models.Reconciled,
|
||||
AccountId: 1,
|
||||
SecurityId: -1,
|
||||
Amount: "-39.99",
|
||||
Amount: NewAmount("-39.99"),
|
||||
},
|
||||
{
|
||||
Status: models.Entered,
|
||||
AccountId: 4,
|
||||
SecurityId: -1,
|
||||
Amount: "39.99",
|
||||
Amount: NewAmount("39.99"),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -370,13 +370,13 @@ var data = []TestData{
|
||||
Status: models.Reconciled,
|
||||
AccountId: 5,
|
||||
SecurityId: -1,
|
||||
Amount: "-24.56",
|
||||
Amount: NewAmount("-24.56"),
|
||||
},
|
||||
{
|
||||
Status: models.Entered,
|
||||
AccountId: 6,
|
||||
SecurityId: -1,
|
||||
Amount: "24.56",
|
||||
Amount: NewAmount("24.56"),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -120,7 +120,7 @@ func ensureTransactionsMatch(t *testing.T, expected, tran *models.Transaction, a
|
||||
origsplit.RemoteId == origsplit.RemoteId &&
|
||||
origsplit.Number == s.Number &&
|
||||
origsplit.Memo == s.Memo &&
|
||||
origsplit.Amount == s.Amount &&
|
||||
origsplit.Amount.Cmp(&s.Amount.Rat) == 0 &&
|
||||
(!matchsplitids || origsplit.SplitId == s.SplitId) {
|
||||
|
||||
if _, ok := foundIds[s.SplitId]; ok {
|
||||
@ -187,13 +187,13 @@ func TestCreateTransaction(t *testing.T) {
|
||||
Status: models.Reconciled,
|
||||
AccountId: d.accounts[1].AccountId,
|
||||
SecurityId: -1,
|
||||
Amount: "-39.98",
|
||||
Amount: NewAmount("-39.98"),
|
||||
},
|
||||
{
|
||||
Status: models.Entered,
|
||||
AccountId: d.accounts[4].AccountId,
|
||||
SecurityId: -1,
|
||||
Amount: "39.99",
|
||||
Amount: NewAmount("39.99"),
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -333,7 +333,7 @@ func TestUpdateTransaction(t *testing.T) {
|
||||
tran.UserId = curr.UserId
|
||||
|
||||
// Make sure we can't create an unbalanced transaction
|
||||
tran.Splits[len(tran.Splits)-1].Amount = "42"
|
||||
tran.Splits[len(tran.Splits)-1].Amount = NewAmount("42")
|
||||
_, err = updateTransaction(d.clients[orig.UserId], tran)
|
||||
if err == nil {
|
||||
t.Fatalf("Expected error updating imbalanced transaction")
|
||||
|
Reference in New Issue
Block a user