mirror of
				https://github.com/aclindsa/moneygo.git
				synced 2025-11-03 18:13:27 -05: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:
		@@ -10,7 +10,6 @@ import (
 | 
			
		||||
	"io"
 | 
			
		||||
	"log"
 | 
			
		||||
	"math"
 | 
			
		||||
	"math/big"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
@@ -49,7 +48,7 @@ func (gc *GnucashCommodity) UnmarshalXML(d *xml.Decoder, start xml.StartElement)
 | 
			
		||||
		gc.Precision = template.Precision
 | 
			
		||||
	} else {
 | 
			
		||||
		if gxc.Fraction > 0 {
 | 
			
		||||
			gc.Precision = int(math.Ceil(math.Log10(float64(gxc.Fraction))))
 | 
			
		||||
			gc.Precision = uint64(math.Ceil(math.Log10(float64(gxc.Fraction))))
 | 
			
		||||
		} else {
 | 
			
		||||
			gc.Precision = 0
 | 
			
		||||
		}
 | 
			
		||||
@@ -178,13 +177,14 @@ func ImportGnucash(r io.Reader) (*GnucashImport, error) {
 | 
			
		||||
		p.CurrencyId = currency.SecurityId
 | 
			
		||||
		p.Date = price.Date.Date.Time
 | 
			
		||||
 | 
			
		||||
		var r big.Rat
 | 
			
		||||
		_, ok = r.SetString(price.Value)
 | 
			
		||||
		if ok {
 | 
			
		||||
			p.Value = r.FloatString(currency.Precision)
 | 
			
		||||
		} else {
 | 
			
		||||
		_, ok = p.Value.SetString(price.Value)
 | 
			
		||||
		if !ok {
 | 
			
		||||
			return nil, fmt.Errorf("Can't set price value: %s", price.Value)
 | 
			
		||||
		}
 | 
			
		||||
		if p.Value.Precision() > currency.Precision {
 | 
			
		||||
			// TODO we're possibly losing data here... but do we care?
 | 
			
		||||
			p.Value.Round(currency.Precision)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		p.RemoteId = "gnucash:" + price.Id
 | 
			
		||||
		gncimport.Prices = append(gncimport.Prices, p)
 | 
			
		||||
@@ -293,13 +293,13 @@ func ImportGnucash(r io.Reader) (*GnucashImport, error) {
 | 
			
		||||
			s.Number = gt.Number
 | 
			
		||||
			s.Memo = gs.Memo
 | 
			
		||||
 | 
			
		||||
			var r big.Rat
 | 
			
		||||
			_, ok = r.SetString(gs.Amount)
 | 
			
		||||
			if ok {
 | 
			
		||||
				s.Amount = r.FloatString(security.Precision)
 | 
			
		||||
			} else {
 | 
			
		||||
			_, ok = s.Amount.SetString(gs.Amount)
 | 
			
		||||
			if !ok {
 | 
			
		||||
				return nil, fmt.Errorf("Can't set split Amount: %s", gs.Amount)
 | 
			
		||||
			}
 | 
			
		||||
			if s.Amount.Precision() > security.Precision {
 | 
			
		||||
				return nil, fmt.Errorf("Imported price's precision (%d) is greater than the security's (%s)\n", s.Amount.Precision(), security)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			t.Splits = append(t.Splits, s)
 | 
			
		||||
		}
 | 
			
		||||
@@ -356,6 +356,7 @@ func GnucashImportHandler(r *http.Request, context *Context) ResponseWriterWrite
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Print(err)
 | 
			
		||||
		return NewError(3 /*Invalid Request*/)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -164,7 +164,11 @@ func ofxImportHelper(tx store.Tx, r io.Reader, user *models.User, accountid int6
 | 
			
		||||
					log.Print(err)
 | 
			
		||||
					return NewError(999 /*Internal Error*/)
 | 
			
		||||
				}
 | 
			
		||||
				split.Amount = r.FloatString(security.Precision)
 | 
			
		||||
				split.Amount.Rat = *r
 | 
			
		||||
				if split.Amount.Precision() > security.Precision {
 | 
			
		||||
					log.Printf("Precision on created imbalance-correction split (%d) greater than the underlying security (%s) allows (%d)", split.Amount.Precision(), security, security.Precision)
 | 
			
		||||
					return NewError(999 /*Internal Error*/)
 | 
			
		||||
				}
 | 
			
		||||
				split.SecurityId = -1
 | 
			
		||||
				split.AccountId = imbalanced_account.AccountId
 | 
			
		||||
				transaction.Splits = append(transaction.Splits, split)
 | 
			
		||||
 
 | 
			
		||||
@@ -97,9 +97,12 @@ func (i *OFXImport) AddTransaction(tran *ofxgo.Transaction, account *models.Acco
 | 
			
		||||
	s1.ImportSplitType = models.ImportAccount
 | 
			
		||||
	s2.ImportSplitType = models.ExternalAccount
 | 
			
		||||
 | 
			
		||||
	s1.Amount.Rat = *amt
 | 
			
		||||
	s2.Amount.Rat = *amt.Neg(amt)
 | 
			
		||||
	security := i.Securities[account.SecurityId-1]
 | 
			
		||||
	s1.Amount = amt.FloatString(security.Precision)
 | 
			
		||||
	s2.Amount = amt.Neg(amt).FloatString(security.Precision)
 | 
			
		||||
	if s1.Amount.Precision() > security.Precision {
 | 
			
		||||
		return errors.New("Imported transaction amount is too precise for security")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	s1.Status = models.Imported
 | 
			
		||||
	s2.Status = models.Imported
 | 
			
		||||
@@ -262,7 +265,7 @@ func (i *OFXImport) GetInvBuyTran(buy *ofxgo.InvBuy, curdef *models.Security, ac
 | 
			
		||||
			SecurityId:      curdef.SecurityId,
 | 
			
		||||
			RemoteId:        "ofx:" + buy.InvTran.FiTID.String(),
 | 
			
		||||
			Memo:            memo + "(commission)",
 | 
			
		||||
			Amount:          commission.FloatString(curdef.Precision),
 | 
			
		||||
			Amount:          models.Amount{commission},
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
	if num := taxes.Num(); !num.IsInt64() || num.Int64() != 0 {
 | 
			
		||||
@@ -274,7 +277,7 @@ func (i *OFXImport) GetInvBuyTran(buy *ofxgo.InvBuy, curdef *models.Security, ac
 | 
			
		||||
			SecurityId:      curdef.SecurityId,
 | 
			
		||||
			RemoteId:        "ofx:" + buy.InvTran.FiTID.String(),
 | 
			
		||||
			Memo:            memo + "(taxes)",
 | 
			
		||||
			Amount:          taxes.FloatString(curdef.Precision),
 | 
			
		||||
			Amount:          models.Amount{taxes},
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
	if num := fees.Num(); !num.IsInt64() || num.Int64() != 0 {
 | 
			
		||||
@@ -286,7 +289,7 @@ func (i *OFXImport) GetInvBuyTran(buy *ofxgo.InvBuy, curdef *models.Security, ac
 | 
			
		||||
			SecurityId:      curdef.SecurityId,
 | 
			
		||||
			RemoteId:        "ofx:" + buy.InvTran.FiTID.String(),
 | 
			
		||||
			Memo:            memo + "(fees)",
 | 
			
		||||
			Amount:          fees.FloatString(curdef.Precision),
 | 
			
		||||
			Amount:          models.Amount{fees},
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
	if num := load.Num(); !num.IsInt64() || num.Int64() != 0 {
 | 
			
		||||
@@ -298,7 +301,7 @@ func (i *OFXImport) GetInvBuyTran(buy *ofxgo.InvBuy, curdef *models.Security, ac
 | 
			
		||||
			SecurityId:      curdef.SecurityId,
 | 
			
		||||
			RemoteId:        "ofx:" + buy.InvTran.FiTID.String(),
 | 
			
		||||
			Memo:            memo + "(load)",
 | 
			
		||||
			Amount:          load.FloatString(curdef.Precision),
 | 
			
		||||
			Amount:          models.Amount{load},
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
	t.Splits = append(t.Splits, &models.Split{
 | 
			
		||||
@@ -309,7 +312,7 @@ func (i *OFXImport) GetInvBuyTran(buy *ofxgo.InvBuy, curdef *models.Security, ac
 | 
			
		||||
		SecurityId:      -1,
 | 
			
		||||
		RemoteId:        "ofx:" + buy.InvTran.FiTID.String(),
 | 
			
		||||
		Memo:            memo,
 | 
			
		||||
		Amount:          total.FloatString(curdef.Precision),
 | 
			
		||||
		Amount:          models.Amount{total},
 | 
			
		||||
	})
 | 
			
		||||
	t.Splits = append(t.Splits, &models.Split{
 | 
			
		||||
		// TODO ReversalFiTID?
 | 
			
		||||
@@ -319,7 +322,7 @@ func (i *OFXImport) GetInvBuyTran(buy *ofxgo.InvBuy, curdef *models.Security, ac
 | 
			
		||||
		SecurityId:      curdef.SecurityId,
 | 
			
		||||
		RemoteId:        "ofx:" + buy.InvTran.FiTID.String(),
 | 
			
		||||
		Memo:            memo,
 | 
			
		||||
		Amount:          tradingTotal.FloatString(curdef.Precision),
 | 
			
		||||
		Amount:          models.Amount{tradingTotal},
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	var units big.Rat
 | 
			
		||||
@@ -332,7 +335,7 @@ func (i *OFXImport) GetInvBuyTran(buy *ofxgo.InvBuy, curdef *models.Security, ac
 | 
			
		||||
		SecurityId:      security.SecurityId,
 | 
			
		||||
		RemoteId:        "ofx:" + buy.InvTran.FiTID.String(),
 | 
			
		||||
		Memo:            memo,
 | 
			
		||||
		Amount:          units.FloatString(security.Precision),
 | 
			
		||||
		Amount:          models.Amount{units},
 | 
			
		||||
	})
 | 
			
		||||
	units.Neg(&units)
 | 
			
		||||
	t.Splits = append(t.Splits, &models.Split{
 | 
			
		||||
@@ -343,7 +346,7 @@ func (i *OFXImport) GetInvBuyTran(buy *ofxgo.InvBuy, curdef *models.Security, ac
 | 
			
		||||
		SecurityId:      security.SecurityId,
 | 
			
		||||
		RemoteId:        "ofx:" + buy.InvTran.FiTID.String(),
 | 
			
		||||
		Memo:            memo,
 | 
			
		||||
		Amount:          units.FloatString(security.Precision),
 | 
			
		||||
		Amount:          models.Amount{units},
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	return &t, nil
 | 
			
		||||
@@ -378,7 +381,7 @@ func (i *OFXImport) GetIncomeTran(income *ofxgo.Income, curdef *models.Security,
 | 
			
		||||
		SecurityId:      -1,
 | 
			
		||||
		RemoteId:        "ofx:" + income.InvTran.FiTID.String(),
 | 
			
		||||
		Memo:            memo,
 | 
			
		||||
		Amount:          total.FloatString(curdef.Precision),
 | 
			
		||||
		Amount:          models.Amount{total},
 | 
			
		||||
	})
 | 
			
		||||
	total.Neg(&total)
 | 
			
		||||
	t.Splits = append(t.Splits, &models.Split{
 | 
			
		||||
@@ -389,7 +392,7 @@ func (i *OFXImport) GetIncomeTran(income *ofxgo.Income, curdef *models.Security,
 | 
			
		||||
		SecurityId:      curdef.SecurityId,
 | 
			
		||||
		RemoteId:        "ofx:" + income.InvTran.FiTID.String(),
 | 
			
		||||
		Memo:            memo,
 | 
			
		||||
		Amount:          total.FloatString(curdef.Precision),
 | 
			
		||||
		Amount:          models.Amount{total},
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	return &t, nil
 | 
			
		||||
@@ -423,7 +426,7 @@ func (i *OFXImport) GetInvExpenseTran(expense *ofxgo.InvExpense, curdef *models.
 | 
			
		||||
		SecurityId:      -1,
 | 
			
		||||
		RemoteId:        "ofx:" + expense.InvTran.FiTID.String(),
 | 
			
		||||
		Memo:            memo,
 | 
			
		||||
		Amount:          total.FloatString(curdef.Precision),
 | 
			
		||||
		Amount:          models.Amount{total},
 | 
			
		||||
	})
 | 
			
		||||
	total.Neg(&total)
 | 
			
		||||
	t.Splits = append(t.Splits, &models.Split{
 | 
			
		||||
@@ -434,7 +437,7 @@ func (i *OFXImport) GetInvExpenseTran(expense *ofxgo.InvExpense, curdef *models.
 | 
			
		||||
		SecurityId:      curdef.SecurityId,
 | 
			
		||||
		RemoteId:        "ofx:" + expense.InvTran.FiTID.String(),
 | 
			
		||||
		Memo:            memo,
 | 
			
		||||
		Amount:          total.FloatString(curdef.Precision),
 | 
			
		||||
		Amount:          models.Amount{total},
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	return &t, nil
 | 
			
		||||
@@ -462,7 +465,7 @@ func (i *OFXImport) GetMarginInterestTran(marginint *ofxgo.MarginInterest, curde
 | 
			
		||||
		SecurityId:      -1,
 | 
			
		||||
		RemoteId:        "ofx:" + marginint.InvTran.FiTID.String(),
 | 
			
		||||
		Memo:            memo,
 | 
			
		||||
		Amount:          total.FloatString(curdef.Precision),
 | 
			
		||||
		Amount:          models.Amount{total},
 | 
			
		||||
	})
 | 
			
		||||
	total.Neg(&total)
 | 
			
		||||
	t.Splits = append(t.Splits, &models.Split{
 | 
			
		||||
@@ -473,7 +476,7 @@ func (i *OFXImport) GetMarginInterestTran(marginint *ofxgo.MarginInterest, curde
 | 
			
		||||
		SecurityId:      curdef.SecurityId,
 | 
			
		||||
		RemoteId:        "ofx:" + marginint.InvTran.FiTID.String(),
 | 
			
		||||
		Memo:            memo,
 | 
			
		||||
		Amount:          total.FloatString(curdef.Precision),
 | 
			
		||||
		Amount:          models.Amount{total},
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	return &t, nil
 | 
			
		||||
@@ -526,7 +529,7 @@ func (i *OFXImport) GetReinvestTran(reinvest *ofxgo.Reinvest, curdef *models.Sec
 | 
			
		||||
			SecurityId:      curdef.SecurityId,
 | 
			
		||||
			RemoteId:        "ofx:" + reinvest.InvTran.FiTID.String(),
 | 
			
		||||
			Memo:            memo + "(commission)",
 | 
			
		||||
			Amount:          commission.FloatString(curdef.Precision),
 | 
			
		||||
			Amount:          models.Amount{commission},
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
	if num := taxes.Num(); !num.IsInt64() || num.Int64() != 0 {
 | 
			
		||||
@@ -538,7 +541,7 @@ func (i *OFXImport) GetReinvestTran(reinvest *ofxgo.Reinvest, curdef *models.Sec
 | 
			
		||||
			SecurityId:      curdef.SecurityId,
 | 
			
		||||
			RemoteId:        "ofx:" + reinvest.InvTran.FiTID.String(),
 | 
			
		||||
			Memo:            memo + "(taxes)",
 | 
			
		||||
			Amount:          taxes.FloatString(curdef.Precision),
 | 
			
		||||
			Amount:          models.Amount{taxes},
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
	if num := fees.Num(); !num.IsInt64() || num.Int64() != 0 {
 | 
			
		||||
@@ -550,7 +553,7 @@ func (i *OFXImport) GetReinvestTran(reinvest *ofxgo.Reinvest, curdef *models.Sec
 | 
			
		||||
			SecurityId:      curdef.SecurityId,
 | 
			
		||||
			RemoteId:        "ofx:" + reinvest.InvTran.FiTID.String(),
 | 
			
		||||
			Memo:            memo + "(fees)",
 | 
			
		||||
			Amount:          fees.FloatString(curdef.Precision),
 | 
			
		||||
			Amount:          models.Amount{fees},
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
	if num := load.Num(); !num.IsInt64() || num.Int64() != 0 {
 | 
			
		||||
@@ -562,7 +565,7 @@ func (i *OFXImport) GetReinvestTran(reinvest *ofxgo.Reinvest, curdef *models.Sec
 | 
			
		||||
			SecurityId:      curdef.SecurityId,
 | 
			
		||||
			RemoteId:        "ofx:" + reinvest.InvTran.FiTID.String(),
 | 
			
		||||
			Memo:            memo + "(load)",
 | 
			
		||||
			Amount:          load.FloatString(curdef.Precision),
 | 
			
		||||
			Amount:          models.Amount{load},
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
	t.Splits = append(t.Splits, &models.Split{
 | 
			
		||||
@@ -573,7 +576,7 @@ func (i *OFXImport) GetReinvestTran(reinvest *ofxgo.Reinvest, curdef *models.Sec
 | 
			
		||||
		SecurityId:      -1,
 | 
			
		||||
		RemoteId:        "ofx:" + reinvest.InvTran.FiTID.String(),
 | 
			
		||||
		Memo:            memo,
 | 
			
		||||
		Amount:          total.FloatString(curdef.Precision),
 | 
			
		||||
		Amount:          models.Amount{total},
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	t.Splits = append(t.Splits, &models.Split{
 | 
			
		||||
@@ -584,7 +587,7 @@ func (i *OFXImport) GetReinvestTran(reinvest *ofxgo.Reinvest, curdef *models.Sec
 | 
			
		||||
		SecurityId:      curdef.SecurityId,
 | 
			
		||||
		RemoteId:        "ofx:" + reinvest.InvTran.FiTID.String(),
 | 
			
		||||
		Memo:            memo,
 | 
			
		||||
		Amount:          total.FloatString(curdef.Precision),
 | 
			
		||||
		Amount:          models.Amount{total},
 | 
			
		||||
	})
 | 
			
		||||
	total.Neg(&total)
 | 
			
		||||
	t.Splits = append(t.Splits, &models.Split{
 | 
			
		||||
@@ -595,7 +598,7 @@ func (i *OFXImport) GetReinvestTran(reinvest *ofxgo.Reinvest, curdef *models.Sec
 | 
			
		||||
		SecurityId:      -1,
 | 
			
		||||
		RemoteId:        "ofx:" + reinvest.InvTran.FiTID.String(),
 | 
			
		||||
		Memo:            memo,
 | 
			
		||||
		Amount:          total.FloatString(curdef.Precision),
 | 
			
		||||
		Amount:          models.Amount{total},
 | 
			
		||||
	})
 | 
			
		||||
	t.Splits = append(t.Splits, &models.Split{
 | 
			
		||||
		// TODO ReversalFiTID?
 | 
			
		||||
@@ -605,7 +608,7 @@ func (i *OFXImport) GetReinvestTran(reinvest *ofxgo.Reinvest, curdef *models.Sec
 | 
			
		||||
		SecurityId:      curdef.SecurityId,
 | 
			
		||||
		RemoteId:        "ofx:" + reinvest.InvTran.FiTID.String(),
 | 
			
		||||
		Memo:            memo,
 | 
			
		||||
		Amount:          tradingTotal.FloatString(curdef.Precision),
 | 
			
		||||
		Amount:          models.Amount{tradingTotal},
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	var units big.Rat
 | 
			
		||||
@@ -618,7 +621,7 @@ func (i *OFXImport) GetReinvestTran(reinvest *ofxgo.Reinvest, curdef *models.Sec
 | 
			
		||||
		SecurityId:      security.SecurityId,
 | 
			
		||||
		RemoteId:        "ofx:" + reinvest.InvTran.FiTID.String(),
 | 
			
		||||
		Memo:            memo,
 | 
			
		||||
		Amount:          units.FloatString(security.Precision),
 | 
			
		||||
		Amount:          models.Amount{units},
 | 
			
		||||
	})
 | 
			
		||||
	units.Neg(&units)
 | 
			
		||||
	t.Splits = append(t.Splits, &models.Split{
 | 
			
		||||
@@ -629,7 +632,7 @@ func (i *OFXImport) GetReinvestTran(reinvest *ofxgo.Reinvest, curdef *models.Sec
 | 
			
		||||
		SecurityId:      security.SecurityId,
 | 
			
		||||
		RemoteId:        "ofx:" + reinvest.InvTran.FiTID.String(),
 | 
			
		||||
		Memo:            memo,
 | 
			
		||||
		Amount:          units.FloatString(security.Precision),
 | 
			
		||||
		Amount:          models.Amount{units},
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	return &t, nil
 | 
			
		||||
@@ -663,7 +666,7 @@ func (i *OFXImport) GetRetOfCapTran(retofcap *ofxgo.RetOfCap, curdef *models.Sec
 | 
			
		||||
		SecurityId:      -1,
 | 
			
		||||
		RemoteId:        "ofx:" + retofcap.InvTran.FiTID.String(),
 | 
			
		||||
		Memo:            memo,
 | 
			
		||||
		Amount:          total.FloatString(curdef.Precision),
 | 
			
		||||
		Amount:          models.Amount{total},
 | 
			
		||||
	})
 | 
			
		||||
	total.Neg(&total)
 | 
			
		||||
	t.Splits = append(t.Splits, &models.Split{
 | 
			
		||||
@@ -674,7 +677,7 @@ func (i *OFXImport) GetRetOfCapTran(retofcap *ofxgo.RetOfCap, curdef *models.Sec
 | 
			
		||||
		SecurityId:      curdef.SecurityId,
 | 
			
		||||
		RemoteId:        "ofx:" + retofcap.InvTran.FiTID.String(),
 | 
			
		||||
		Memo:            memo,
 | 
			
		||||
		Amount:          total.FloatString(curdef.Precision),
 | 
			
		||||
		Amount:          models.Amount{total},
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	return &t, nil
 | 
			
		||||
@@ -730,7 +733,7 @@ func (i *OFXImport) GetInvSellTran(sell *ofxgo.InvSell, curdef *models.Security,
 | 
			
		||||
			SecurityId:      curdef.SecurityId,
 | 
			
		||||
			RemoteId:        "ofx:" + sell.InvTran.FiTID.String(),
 | 
			
		||||
			Memo:            memo + "(commission)",
 | 
			
		||||
			Amount:          commission.FloatString(curdef.Precision),
 | 
			
		||||
			Amount:          models.Amount{commission},
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
	if num := taxes.Num(); !num.IsInt64() || num.Int64() != 0 {
 | 
			
		||||
@@ -742,7 +745,7 @@ func (i *OFXImport) GetInvSellTran(sell *ofxgo.InvSell, curdef *models.Security,
 | 
			
		||||
			SecurityId:      curdef.SecurityId,
 | 
			
		||||
			RemoteId:        "ofx:" + sell.InvTran.FiTID.String(),
 | 
			
		||||
			Memo:            memo + "(taxes)",
 | 
			
		||||
			Amount:          taxes.FloatString(curdef.Precision),
 | 
			
		||||
			Amount:          models.Amount{taxes},
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
	if num := fees.Num(); !num.IsInt64() || num.Int64() != 0 {
 | 
			
		||||
@@ -754,7 +757,7 @@ func (i *OFXImport) GetInvSellTran(sell *ofxgo.InvSell, curdef *models.Security,
 | 
			
		||||
			SecurityId:      curdef.SecurityId,
 | 
			
		||||
			RemoteId:        "ofx:" + sell.InvTran.FiTID.String(),
 | 
			
		||||
			Memo:            memo + "(fees)",
 | 
			
		||||
			Amount:          fees.FloatString(curdef.Precision),
 | 
			
		||||
			Amount:          models.Amount{fees},
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
	if num := load.Num(); !num.IsInt64() || num.Int64() != 0 {
 | 
			
		||||
@@ -766,7 +769,7 @@ func (i *OFXImport) GetInvSellTran(sell *ofxgo.InvSell, curdef *models.Security,
 | 
			
		||||
			SecurityId:      curdef.SecurityId,
 | 
			
		||||
			RemoteId:        "ofx:" + sell.InvTran.FiTID.String(),
 | 
			
		||||
			Memo:            memo + "(load)",
 | 
			
		||||
			Amount:          load.FloatString(curdef.Precision),
 | 
			
		||||
			Amount:          models.Amount{load},
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
	t.Splits = append(t.Splits, &models.Split{
 | 
			
		||||
@@ -777,7 +780,7 @@ func (i *OFXImport) GetInvSellTran(sell *ofxgo.InvSell, curdef *models.Security,
 | 
			
		||||
		SecurityId:      -1,
 | 
			
		||||
		RemoteId:        "ofx:" + sell.InvTran.FiTID.String(),
 | 
			
		||||
		Memo:            memo,
 | 
			
		||||
		Amount:          total.FloatString(curdef.Precision),
 | 
			
		||||
		Amount:          models.Amount{total},
 | 
			
		||||
	})
 | 
			
		||||
	t.Splits = append(t.Splits, &models.Split{
 | 
			
		||||
		// TODO ReversalFiTID?
 | 
			
		||||
@@ -787,7 +790,7 @@ func (i *OFXImport) GetInvSellTran(sell *ofxgo.InvSell, curdef *models.Security,
 | 
			
		||||
		SecurityId:      curdef.SecurityId,
 | 
			
		||||
		RemoteId:        "ofx:" + sell.InvTran.FiTID.String(),
 | 
			
		||||
		Memo:            memo,
 | 
			
		||||
		Amount:          tradingTotal.FloatString(curdef.Precision),
 | 
			
		||||
		Amount:          models.Amount{tradingTotal},
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	var units big.Rat
 | 
			
		||||
@@ -800,7 +803,7 @@ func (i *OFXImport) GetInvSellTran(sell *ofxgo.InvSell, curdef *models.Security,
 | 
			
		||||
		SecurityId:      security.SecurityId,
 | 
			
		||||
		RemoteId:        "ofx:" + sell.InvTran.FiTID.String(),
 | 
			
		||||
		Memo:            memo,
 | 
			
		||||
		Amount:          units.FloatString(security.Precision),
 | 
			
		||||
		Amount:          models.Amount{units},
 | 
			
		||||
	})
 | 
			
		||||
	units.Neg(&units)
 | 
			
		||||
	t.Splits = append(t.Splits, &models.Split{
 | 
			
		||||
@@ -811,7 +814,7 @@ func (i *OFXImport) GetInvSellTran(sell *ofxgo.InvSell, curdef *models.Security,
 | 
			
		||||
		SecurityId:      security.SecurityId,
 | 
			
		||||
		RemoteId:        "ofx:" + sell.InvTran.FiTID.String(),
 | 
			
		||||
		Memo:            memo,
 | 
			
		||||
		Amount:          units.FloatString(security.Precision),
 | 
			
		||||
		Amount:          models.Amount{units},
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	return &t, nil
 | 
			
		||||
@@ -842,7 +845,7 @@ func (i *OFXImport) GetTransferTran(transfer *ofxgo.Transfer, account *models.Ac
 | 
			
		||||
		SecurityId:      security.SecurityId,
 | 
			
		||||
		RemoteId:        "ofx:" + transfer.InvTran.FiTID.String(),
 | 
			
		||||
		Memo:            memo,
 | 
			
		||||
		Amount:          units.FloatString(security.Precision),
 | 
			
		||||
		Amount:          models.Amount{units},
 | 
			
		||||
	})
 | 
			
		||||
	units.Neg(&units)
 | 
			
		||||
	t.Splits = append(t.Splits, &models.Split{
 | 
			
		||||
@@ -853,7 +856,7 @@ func (i *OFXImport) GetTransferTran(transfer *ofxgo.Transfer, account *models.Ac
 | 
			
		||||
		SecurityId:      security.SecurityId,
 | 
			
		||||
		RemoteId:        "ofx:" + transfer.InvTran.FiTID.String(),
 | 
			
		||||
		Memo:            memo,
 | 
			
		||||
		Amount:          units.FloatString(security.Precision),
 | 
			
		||||
		Amount:          models.Amount{units},
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	return &t, nil
 | 
			
		||||
 
 | 
			
		||||
@@ -31,9 +31,8 @@ func GetTransactionImbalances(tx store.Tx, t *models.Transaction) (map[int64]big
 | 
			
		||||
			}
 | 
			
		||||
			securityid = account.SecurityId
 | 
			
		||||
		}
 | 
			
		||||
		amount, _ := t.Splits[i].GetAmount()
 | 
			
		||||
		sum := sums[securityid]
 | 
			
		||||
		(&sum).Add(&sum, amount)
 | 
			
		||||
		(&sum).Add(&sum, &t.Splits[i].Amount.Rat)
 | 
			
		||||
		sums[securityid] = sum
 | 
			
		||||
	}
 | 
			
		||||
	return sums, nil
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user