mirror of
https://github.com/aclindsa/moneygo.git
synced 2024-11-16 19:40:05 -05:00
266 lines
6.8 KiB
Go
266 lines
6.8 KiB
Go
package handlers
|
|
|
|
//go:generate make
|
|
|
|
import (
|
|
"errors"
|
|
"github.com/aclindsa/moneygo/internal/models"
|
|
"github.com/aclindsa/moneygo/internal/store"
|
|
"log"
|
|
"net/http"
|
|
"net/url"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
func SearchSecurityTemplates(search string, _type models.SecurityType, limit int64) []*models.Security {
|
|
upperSearch := strings.ToUpper(search)
|
|
var results []*models.Security
|
|
for i, security := range SecurityTemplates {
|
|
if strings.Contains(strings.ToUpper(security.Name), upperSearch) ||
|
|
strings.Contains(strings.ToUpper(security.Description), upperSearch) ||
|
|
strings.Contains(strings.ToUpper(security.Symbol), upperSearch) {
|
|
if _type == 0 || _type == security.Type {
|
|
results = append(results, &SecurityTemplates[i])
|
|
if limit != -1 && int64(len(results)) >= limit {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return results
|
|
}
|
|
|
|
func FindSecurityTemplate(name string, _type models.SecurityType) *models.Security {
|
|
for _, security := range SecurityTemplates {
|
|
if name == security.Name && _type == security.Type {
|
|
return &security
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func FindCurrencyTemplate(iso4217 int64) *models.Security {
|
|
iso4217string := strconv.FormatInt(iso4217, 10)
|
|
for _, security := range SecurityTemplates {
|
|
if security.Type == models.Currency && security.AlternateId == iso4217string {
|
|
return &security
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func UpdateSecurity(tx store.Tx, s *models.Security) (err error) {
|
|
user, err := tx.GetUser(s.UserId)
|
|
if err != nil {
|
|
return
|
|
} else if user.DefaultCurrency == s.SecurityId && s.Type != models.Currency {
|
|
return errors.New("Cannot change security which is user's default currency to be non-currency")
|
|
}
|
|
|
|
err = tx.UpdateSecurity(s)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func ImportGetCreateSecurity(tx store.Tx, userid int64, security *models.Security) (*models.Security, error) {
|
|
security.UserId = userid
|
|
if len(security.AlternateId) == 0 {
|
|
// Always create a new local security if we can't match on the AlternateId
|
|
err := tx.InsertSecurity(security)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return security, nil
|
|
}
|
|
|
|
securities, err := tx.FindMatchingSecurities(security)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// First try to find a case insensitive match on the name or symbol
|
|
upperName := strings.ToUpper(security.Name)
|
|
upperSymbol := strings.ToUpper(security.Symbol)
|
|
for _, s := range *securities {
|
|
if (len(s.Name) > 0 && strings.ToUpper(s.Name) == upperName) ||
|
|
(len(s.Symbol) > 0 && strings.ToUpper(s.Symbol) == upperSymbol) {
|
|
return s, nil
|
|
}
|
|
}
|
|
// if strings.Contains(strings.ToUpper(security.Name), upperSearch) ||
|
|
|
|
// Try to find a partial string match on the name or symbol
|
|
for _, s := range *securities {
|
|
sUpperName := strings.ToUpper(s.Name)
|
|
sUpperSymbol := strings.ToUpper(s.Symbol)
|
|
if (len(upperName) > 0 && len(s.Name) > 0 && (strings.Contains(upperName, sUpperName) || strings.Contains(sUpperName, upperName))) ||
|
|
(len(upperSymbol) > 0 && len(s.Symbol) > 0 && (strings.Contains(upperSymbol, sUpperSymbol) || strings.Contains(sUpperSymbol, upperSymbol))) {
|
|
return s, nil
|
|
}
|
|
}
|
|
|
|
// Give up and return the first security in the list
|
|
if len(*securities) > 0 {
|
|
return (*securities)[0], nil
|
|
}
|
|
|
|
// If there wasn't even one security in the list, make a new one
|
|
err = tx.InsertSecurity(security)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return security, nil
|
|
}
|
|
|
|
func SecurityHandler(r *http.Request, context *Context) ResponseWriterWriter {
|
|
user, err := GetUserFromSession(context.Tx, r)
|
|
if err != nil {
|
|
return NewError(1 /*Not Signed In*/)
|
|
}
|
|
|
|
if r.Method == "POST" {
|
|
if !context.LastLevel() {
|
|
securityid, err := context.NextID()
|
|
if err != nil {
|
|
return NewError(3 /*Invalid Request*/)
|
|
}
|
|
if context.NextLevel() != "prices" {
|
|
return NewError(3 /*Invalid Request*/)
|
|
}
|
|
return PriceHandler(r, context, user, securityid)
|
|
}
|
|
|
|
var security models.Security
|
|
if err := ReadJSON(r, &security); err != nil {
|
|
return NewError(3 /*Invalid Request*/)
|
|
}
|
|
security.SecurityId = -1
|
|
security.UserId = user.UserId
|
|
|
|
err = context.Tx.InsertSecurity(&security)
|
|
if err != nil {
|
|
log.Print(err)
|
|
return NewError(999 /*Internal Error*/)
|
|
}
|
|
|
|
return ResponseWrapper{201, &security}
|
|
} else if r.Method == "GET" {
|
|
if context.LastLevel() {
|
|
//Return all securities
|
|
var sl models.SecurityList
|
|
|
|
securities, err := context.Tx.GetSecurities(user.UserId)
|
|
if err != nil {
|
|
log.Print(err)
|
|
return NewError(999 /*Internal Error*/)
|
|
}
|
|
|
|
sl.Securities = securities
|
|
return &sl
|
|
} else {
|
|
securityid, err := context.NextID()
|
|
if err != nil {
|
|
return NewError(3 /*Invalid Request*/)
|
|
}
|
|
|
|
if !context.LastLevel() {
|
|
if context.NextLevel() != "prices" {
|
|
return NewError(3 /*Invalid Request*/)
|
|
}
|
|
return PriceHandler(r, context, user, securityid)
|
|
}
|
|
|
|
security, err := context.Tx.GetSecurity(securityid, user.UserId)
|
|
if err != nil {
|
|
return NewError(3 /*Invalid Request*/)
|
|
}
|
|
|
|
return security
|
|
}
|
|
} else {
|
|
securityid, err := context.NextID()
|
|
if err != nil {
|
|
return NewError(3 /*Invalid Request*/)
|
|
}
|
|
if !context.LastLevel() {
|
|
if context.NextLevel() != "prices" {
|
|
return NewError(3 /*Invalid Request*/)
|
|
}
|
|
return PriceHandler(r, context, user, securityid)
|
|
}
|
|
|
|
if r.Method == "PUT" {
|
|
var security models.Security
|
|
if err := ReadJSON(r, &security); err != nil || security.SecurityId != securityid {
|
|
return NewError(3 /*Invalid Request*/)
|
|
}
|
|
security.UserId = user.UserId
|
|
|
|
err = UpdateSecurity(context.Tx, &security)
|
|
if err != nil {
|
|
log.Print(err)
|
|
return NewError(999 /*Internal Error*/)
|
|
}
|
|
|
|
return &security
|
|
} else if r.Method == "DELETE" {
|
|
security, err := context.Tx.GetSecurity(securityid, user.UserId)
|
|
if err != nil {
|
|
return NewError(3 /*Invalid Request*/)
|
|
}
|
|
|
|
err = context.Tx.DeleteSecurity(security)
|
|
if _, ok := err.(store.SecurityInUseError); ok {
|
|
return NewError(7 /*In Use Error*/)
|
|
} else if err != nil {
|
|
log.Print(err)
|
|
return NewError(999 /*Internal Error*/)
|
|
}
|
|
|
|
return SuccessWriter{}
|
|
}
|
|
}
|
|
return NewError(3 /*Invalid Request*/)
|
|
}
|
|
|
|
func SecurityTemplateHandler(r *http.Request, context *Context) ResponseWriterWriter {
|
|
if r.Method == "GET" {
|
|
var sl models.SecurityList
|
|
|
|
query, _ := url.ParseQuery(r.URL.RawQuery)
|
|
|
|
var limit int64 = -1
|
|
search := query.Get("search")
|
|
|
|
var _type models.SecurityType = 0
|
|
typestring := query.Get("type")
|
|
if len(typestring) > 0 {
|
|
_type = models.GetSecurityType(typestring)
|
|
if _type == 0 {
|
|
return NewError(3 /*Invalid Request*/)
|
|
}
|
|
}
|
|
|
|
limitstring := query.Get("limit")
|
|
if limitstring != "" {
|
|
limitint, err := strconv.ParseInt(limitstring, 10, 0)
|
|
if err != nil {
|
|
return NewError(3 /*Invalid Request*/)
|
|
}
|
|
limit = limitint
|
|
}
|
|
|
|
securities := SearchSecurityTemplates(search, _type, limit)
|
|
|
|
sl.Securities = &securities
|
|
return &sl
|
|
} else {
|
|
return NewError(3 /*Invalid Request*/)
|
|
}
|
|
}
|