diff --git a/script/config.go b/script/config.go index cf7b2e0..e592185 100644 --- a/script/config.go +++ b/script/config.go @@ -26,10 +26,14 @@ type Config struct { } type Account struct { - Acc string `json:"account"` - Commodity string `json:"commodity"` - StartDate string `json:"startDate"` - EndDate string `json:"endDate"` + Acc string `json:"account"` + StartDate string `json:"startDate"` + Commodity string `json:"commodity,omitempty"` + PriceAmount string `json:"priceAmount,omitempty"` + PriceCommodity string `json:"priceCommodity,omitempty"` + PriceCommoditySymbol string `json:"priceCommoditySymbol,omitempty"` + EndDate string `json:"endDate,omitempty"` + Type *AccountType `json:"type,omitempty"` } type AccountType struct { @@ -77,6 +81,24 @@ func GetLedgerAccountTypes(ledgerId string) map[string]string { return ledgerAccountTypesMap[ledgerId] } +func GetAccountType(ledgerId string, acc string) AccountType { + accountTypes := ledgerAccountTypesMap[ledgerId] + accNodes := strings.Split(acc, ":") + accountType := AccountType{ + Key: acc, + // 默认取最后一个节点 + Name: accNodes[len(accNodes)-1], + } + var matchKey string = "" + for key, name := range accountTypes { + if strings.Contains(acc, key) && len(matchKey) < len(key) { + matchKey = key + accountType = AccountType{Key: key, Name: name} + } + } + return accountType +} + func IsInWhiteList(ledgerId string) bool { // ledger white list is empty, return true if whiteList == nil || len(whiteList) == 0 { @@ -160,7 +182,7 @@ func LoadLedgerAccountsMap() error { if len(words) >= 3 { key := words[2] temp = accountMap[key] - account := Account{Acc: key} + account := Account{Acc: key, Type: nil} // 货币单位 if len(words) >= 4 { account.Commodity = words[3] @@ -233,5 +255,5 @@ func GetCommoditySymbol(commodity string) string { case "USD": return "$" } - return "" + return commodity } diff --git a/server.go b/server.go index 1c84783..615d3ae 100644 --- a/server.go +++ b/server.go @@ -50,6 +50,7 @@ func RegisterRouter(router *gin.Engine) { { // need authorized authorized.GET("/account/valid", service.QueryValidAccount) + authorized.GET("/account/all", service.QueryAllAccount) authorized.GET("/account/type", service.QueryAccountType) authorized.GET("/stats/months", service.MonthsList) authorized.GET("/stats/total", service.StatsTotal) diff --git a/service/accounts.go b/service/accounts.go index aef8f41..7d8d3f6 100644 --- a/service/accounts.go +++ b/service/accounts.go @@ -1,9 +1,11 @@ package service import ( + "fmt" "github.com/beancount-gs/script" "github.com/gin-gonic/gin" "sort" + "strings" ) func QueryValidAccount(c *gin.Context) { @@ -11,6 +13,49 @@ func QueryValidAccount(c *gin.Context) { OK(c, script.GetLedgerAccounts(ledgerConfig.Id)) } +type accountPosition struct { + Account string `json:"account"` + Position string `json:"position"` +} + +func QueryAllAccount(c *gin.Context) { + ledgerConfig := script.GetLedgerConfigFromContext(c) + + bql := fmt.Sprintf("select '\\', account, '\\', sum(convert(value(position), '%s')), '\\'", ledgerConfig.OperatingCurrency) + accountPositions := make([]accountPosition, 0) + err := script.BQLQueryListByCustomSelect(ledgerConfig, bql, nil, &accountPositions) + if err != nil { + InternalError(c, err.Error()) + return + } + // 将查询结果放入 map 中方便查询账户金额 + accountPositionMap := make(map[string]accountPosition) + for _, ap := range accountPositions { + accountPositionMap[ap.Account] = ap + } + + accounts := script.GetLedgerAccounts(ledgerConfig.Id) + result := make([]script.Account, 0, len(accounts)) + for i := 0; i < len(accounts); i++ { + // 过滤已结束的账户 + if accounts[i].EndDate != "" { + continue + } + key := accounts[i].Acc + typ := script.GetAccountType(ledgerConfig.Id, key) + accounts[i].Type = &typ + position := strings.Trim(accountPositionMap[key].Position, " ") + if position != "" { + fields := strings.Fields(position) + accounts[i].PriceAmount = fields[0] + accounts[i].PriceCommodity = fields[1] + accounts[i].PriceCommoditySymbol = script.GetCommoditySymbol(fields[1]) + } + result = append(result, accounts[i]) + } + OK(c, result) +} + func QueryAccountType(c *gin.Context) { ledgerConfig := script.GetLedgerConfigFromContext(c) accountTypes := script.GetLedgerAccountTypes(ledgerConfig.Id)