1
0
mirror of https://github.com/aclindsa/moneygo.git synced 2024-11-01 00:10:06 -04:00
moneygo/internal/handlers/accounts_lua.go

224 lines
5.6 KiB
Go
Raw Normal View History

package handlers
2017-01-27 11:04:39 -05:00
import (
"context"
"errors"
"github.com/aclindsa/moneygo/internal/models"
2017-12-09 05:56:45 -05:00
"github.com/aclindsa/moneygo/internal/store"
2017-01-27 11:04:39 -05:00
"github.com/yuin/gopher-lua"
2017-02-08 05:40:51 -05:00
"strings"
2017-01-27 11:04:39 -05:00
)
const luaAccountTypeName = "account"
func luaContextGetAccounts(L *lua.LState) (map[int64]*models.Account, error) {
var account_map map[int64]*models.Account
2017-01-27 11:04:39 -05:00
ctx := L.Context()
2017-12-09 05:56:45 -05:00
tx, ok := ctx.Value(dbContextKey).(store.Tx)
if !ok {
return nil, errors.New("Couldn't find tx in lua's Context")
}
account_map, ok = ctx.Value(accountsContextKey).(map[int64]*models.Account)
2017-01-27 11:04:39 -05:00
if !ok {
user, ok := ctx.Value(userContextKey).(*models.User)
2017-01-27 11:04:39 -05:00
if !ok {
return nil, errors.New("Couldn't find User in lua's Context")
}
2017-12-07 20:47:55 -05:00
accounts, err := tx.GetAccounts(user.UserId)
2017-01-27 11:04:39 -05:00
if err != nil {
return nil, err
}
account_map = make(map[int64]*models.Account)
2017-01-27 11:04:39 -05:00
for i := range *accounts {
2017-12-07 20:47:55 -05:00
account_map[(*accounts)[i].AccountId] = (*accounts)[i]
2017-01-27 11:04:39 -05:00
}
ctx = context.WithValue(ctx, accountsContextKey, account_map)
L.SetContext(ctx)
}
return account_map, nil
}
func luaGetAccounts(L *lua.LState) int {
account_map, err := luaContextGetAccounts(L)
if err != nil {
panic("luaGetAccounts couldn't fetch accounts")
}
table := L.NewTable()
for accountid := range account_map {
table.RawSetInt(int(accountid), AccountToLua(L, account_map[accountid]))
}
L.Push(table)
return 1
}
func luaRegisterAccounts(L *lua.LState) {
mt := L.NewTypeMetatable(luaAccountTypeName)
L.SetGlobal("account", mt)
L.SetField(mt, "__index", L.NewFunction(luaAccount__index))
L.SetField(mt, "__tostring", L.NewFunction(luaAccount__tostring))
L.SetField(mt, "__eq", L.NewFunction(luaAccount__eq))
L.SetField(mt, "__metatable", lua.LString("protected"))
2017-01-30 21:04:18 -05:00
for _, accttype := range models.AccountTypes {
2017-02-08 05:40:51 -05:00
L.SetField(mt, accttype.String(), lua.LNumber(float64(accttype)))
}
2017-01-27 11:04:39 -05:00
getAccountsFn := L.NewFunction(luaGetAccounts)
L.SetField(mt, "get_all", getAccountsFn)
// also register the get_accounts function as a global in its own right
L.SetGlobal("get_accounts", getAccountsFn)
}
func AccountToLua(L *lua.LState, account *models.Account) *lua.LUserData {
2017-01-27 11:04:39 -05:00
ud := L.NewUserData()
ud.Value = account
L.SetMetatable(ud, L.GetTypeMetatable(luaAccountTypeName))
return ud
}
// Checks whether the first lua argument is a *LUserData with *Account and returns this *Account.
func luaCheckAccount(L *lua.LState, n int) *models.Account {
2017-01-27 11:04:39 -05:00
ud := L.CheckUserData(n)
if account, ok := ud.Value.(*models.Account); ok {
2017-01-27 11:04:39 -05:00
return account
}
L.ArgError(n, "account expected")
return nil
}
func luaAccount__index(L *lua.LState) int {
a := luaCheckAccount(L, 1)
field := L.CheckString(2)
switch field {
case "AccountId", "accountid":
L.Push(lua.LNumber(float64(a.AccountId)))
case "Security", "security":
security_map, err := luaContextGetSecurities(L)
if err != nil {
panic("account.security couldn't fetch securities")
}
if security, ok := security_map[a.SecurityId]; ok {
L.Push(SecurityToLua(L, security))
} else {
panic("SecurityId not in lua security_map")
}
2017-06-25 06:14:44 -04:00
case "SecurityId", "securityid":
L.Push(lua.LNumber(float64(a.SecurityId)))
2017-01-27 11:04:39 -05:00
case "Parent", "parent", "ParentAccount", "parentaccount":
if a.ParentAccountId == -1 {
L.Push(lua.LNil)
} else {
account_map, err := luaContextGetAccounts(L)
if err != nil {
panic("account.parent couldn't fetch accounts")
}
if parent, ok := account_map[a.ParentAccountId]; ok {
L.Push(AccountToLua(L, parent))
} else {
panic("ParentAccountId not in lua account_map")
}
}
case "Name", "name":
L.Push(lua.LString(a.Name))
case "Type", "type":
L.Push(lua.LNumber(float64(a.Type)))
2017-02-08 05:40:51 -05:00
case "TypeName", "Typename":
L.Push(lua.LString(a.Type.String()))
case "typename":
L.Push(lua.LString(strings.ToLower(a.Type.String())))
2017-01-27 21:50:02 -05:00
case "Balance", "balance":
2017-01-30 21:04:18 -05:00
L.Push(L.NewFunction(luaAccountBalance))
2017-01-27 11:04:39 -05:00
default:
L.ArgError(2, "unexpected account attribute: "+field)
}
return 1
}
2017-01-30 21:04:18 -05:00
func luaAccountBalance(L *lua.LState) int {
a := luaCheckAccount(L, 1)
ctx := L.Context()
2017-12-09 05:56:45 -05:00
tx, ok := ctx.Value(dbContextKey).(store.Tx)
if !ok {
panic("Couldn't find tx in lua's Context")
}
user, ok := ctx.Value(userContextKey).(*models.User)
2017-01-30 21:04:18 -05:00
if !ok {
panic("Couldn't find User in lua's Context")
}
security_map, err := luaContextGetSecurities(L)
if err != nil {
panic("account.security couldn't fetch securities")
}
security, ok := security_map[a.SecurityId]
if !ok {
panic("SecurityId not in lua security_map")
}
date := luaWeakCheckTime(L, 2)
2017-12-08 21:27:03 -05:00
var splits *[]*models.Split
2017-01-30 21:04:18 -05:00
if date != nil {
end := luaWeakCheckTime(L, 3)
if end != nil {
2017-12-08 21:27:03 -05:00
splits, err = tx.GetAccountSplitsDateRange(user, a.AccountId, date, end)
2017-01-30 21:04:18 -05:00
} else {
2017-12-08 21:27:03 -05:00
splits, err = tx.GetAccountSplitsDate(user, a.AccountId, date)
2017-01-30 21:04:18 -05:00
}
} else {
2017-12-08 21:27:03 -05:00
splits, err = tx.GetAccountSplits(user, a.AccountId)
2017-01-30 21:04:18 -05:00
}
if err != nil {
2017-12-08 21:27:03 -05:00
panic("Failed to fetch splits for account:" + err.Error())
2017-01-30 21:04:18 -05:00
}
2017-12-08 21:27:03 -05:00
rat, err := BalanceFromSplits(splits)
if err != nil {
panic("Failed to calculate balance for account:" + err.Error())
}
b := &Balance{
Amount: rat,
Security: security,
}
L.Push(BalanceToLua(L, b))
2017-01-30 21:04:18 -05:00
return 1
}
2017-01-27 11:04:39 -05:00
func luaAccount__tostring(L *lua.LState) int {
a := luaCheckAccount(L, 1)
account_map, err := luaContextGetAccounts(L)
if err != nil {
panic("luaGetAccounts couldn't fetch accounts")
}
full_name := a.Name
for a.ParentAccountId != -1 {
a = account_map[a.ParentAccountId]
full_name = a.Name + "/" + full_name
}
L.Push(lua.LString(full_name))
return 1
}
func luaAccount__eq(L *lua.LState) int {
a := luaCheckAccount(L, 1)
b := luaCheckAccount(L, 2)
L.Push(lua.LBool(a.AccountId == b.AccountId))
return 1
}