diff --git a/imports.go b/imports.go index 7d25c44..d1fdb38 100644 --- a/imports.go +++ b/imports.go @@ -4,6 +4,7 @@ import ( "io" "io/ioutil" "log" + "math/big" "net/http" "os" ) @@ -62,24 +63,87 @@ func AccountImportHandler(w http.ResponseWriter, r *http.Request, user *User, ac return } + var transactions []Transaction for _, transaction := range *itl.Transactions { + transaction.UserId = user.UserId + transaction.Status = Imported + if !transaction.Valid() { WriteError(w, 3 /*Invalid Request*/) return } - // TODO check if transactions are balanced too - // balanced, err := transaction.Balanced() - // if !balanced || err != nil { - // WriteError(w, 3 /*Invalid Request*/) - // return - // } + imbalances, err := transaction.GetImbalances() + if err != nil { + WriteError(w, 999 /*Internal Error*/) + log.Print(err) + return + } + + // Fixup any imbalances in transactions + var zero big.Rat + var num_imbalances int + for _, imbalance := range imbalances { + if imbalance.Cmp(&zero) != 0 { + num_imbalances += 1 + } + } + + for imbalanced_security, imbalance := range imbalances { + if imbalance.Cmp(&zero) != 0 { + var imbalanced_account *Account + // If we're dealing with exactly two securities, assume any imbalances + // from imports are from trading currencies/securities + if num_imbalances == 2 { + imbalanced_account, err = GetTradingAccount(user.UserId, imbalanced_security) + } else { + imbalanced_account, err = GetImbalanceAccount(user.UserId, imbalanced_security) + } + if err != nil { + WriteError(w, 999 /*Internal Error*/) + log.Print(err) + return + } + + // Add new split to fixup imbalance + split := new(Split) + r := new(big.Rat) + r.Neg(&imbalance) + security := GetSecurity(imbalanced_security) + split.Amount = r.FloatString(security.Precision) + split.SecurityId = -1 + split.AccountId = imbalanced_account.AccountId + transaction.Splits = append(transaction.Splits, split) + } + } + + // Move any splits with SecurityId but not AccountId to Imbalances + // accounts + for _, split := range transaction.Splits { + if split.SecurityId != -1 || split.AccountId == -1 { + imbalanced_account, err := GetImbalanceAccount(user.UserId, split.SecurityId) + if err != nil { + WriteError(w, 999 /*Internal Error*/) + log.Print(err) + return + } + + split.AccountId = imbalanced_account.AccountId + split.SecurityId = -1 + } + } + + balanced, err := transaction.Balanced() + if !balanced || err != nil { + WriteError(w, 999 /*Internal Error*/) + log.Print(err) + return + } + + transactions = append(transactions, transaction) } - /////////////////////// TODO //////////////////////// - for _, transaction := range *itl.Transactions { - transaction.UserId = user.UserId - transaction.Status = Imported + for _, transaction := range transactions { err := InsertTransaction(&transaction, user) if err != nil { WriteError(w, 999 /*Internal Error*/)