opti: multi commodity
This commit is contained in:
parent
29ca04a476
commit
a40875e78b
|
|
@ -30,14 +30,21 @@ type Config struct {
|
|||
}
|
||||
|
||||
type Account struct {
|
||||
Acc string `json:"account"`
|
||||
StartDate string `json:"startDate"`
|
||||
Currency string `json:"currency,omitempty"`
|
||||
MarketNumber string `json:"marketNumber,omitempty"`
|
||||
MarketCurrency string `json:"marketCurrency,omitempty"`
|
||||
MarketCurrencySymbol string `json:"marketCurrencySymbol,omitempty"`
|
||||
EndDate string `json:"endDate,omitempty"`
|
||||
Type *AccountType `json:"type,omitempty"`
|
||||
Acc string `json:"account"`
|
||||
StartDate string `json:"startDate"`
|
||||
Currency string `json:"currency,omitempty"`
|
||||
Positions []AccountPosition `json:"positions,omitempty"`
|
||||
MarketNumber string `json:"marketNumber,omitempty"`
|
||||
MarketCurrency string `json:"marketCurrency,omitempty"`
|
||||
MarketCurrencySymbol string `json:"marketCurrencySymbol,omitempty"`
|
||||
EndDate string `json:"endDate,omitempty"`
|
||||
Type *AccountType `json:"type,omitempty"`
|
||||
}
|
||||
|
||||
type AccountPosition struct {
|
||||
Number string `json:"number,omitempty"`
|
||||
Currency string `json:"currency,omitempty"`
|
||||
CurrencySymbol string `json:"currencySymbol,omitempty"`
|
||||
}
|
||||
|
||||
type AccountType struct {
|
||||
|
|
@ -371,11 +378,27 @@ func EqualServerSecret(secret string) bool {
|
|||
func GetCommoditySymbol(commodity string) string {
|
||||
switch commodity {
|
||||
case "CNY":
|
||||
return "¥"
|
||||
return "¥"
|
||||
case "USD":
|
||||
return "$"
|
||||
case "EUR":
|
||||
return "€"
|
||||
case "JPY":
|
||||
return "¥"
|
||||
case "GBP":
|
||||
return "£"
|
||||
case "AUD":
|
||||
return "$"
|
||||
case "CAD":
|
||||
return "$"
|
||||
case "INR":
|
||||
return "₹"
|
||||
case "RUB":
|
||||
return "₽"
|
||||
case "BRL":
|
||||
return "R$"
|
||||
}
|
||||
return ""
|
||||
return commodity
|
||||
}
|
||||
|
||||
func GetAccountPrefix(account string) string {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import (
|
|||
"fmt"
|
||||
"github.com/beancount-gs/script"
|
||||
"github.com/gin-gonic/gin"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
|
@ -23,14 +24,15 @@ func QueryValidAccount(c *gin.Context) {
|
|||
}
|
||||
|
||||
type accountPosition struct {
|
||||
Account string `json:"account"`
|
||||
Position string `json:"position"`
|
||||
Account string `json:"account"`
|
||||
MarketPosition string `json:"market_position"`
|
||||
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)
|
||||
bql := fmt.Sprintf("select '\\', account, '\\', sum(convert(value(position), '%s')) as market_position, '\\', sum(value(position)) as position, '\\'", ledgerConfig.OperatingCurrency)
|
||||
accountPositions := make([]accountPosition, 0)
|
||||
err := script.BQLQueryListByCustomSelect(ledgerConfig, bql, nil, &accountPositions)
|
||||
if err != nil {
|
||||
|
|
@ -54,18 +56,51 @@ func QueryAllAccount(c *gin.Context) {
|
|||
key := account.Acc
|
||||
typ := script.GetAccountType(ledgerConfig.Id, key)
|
||||
account.Type = &typ
|
||||
position := strings.Trim(accountPositionMap[key].Position, " ")
|
||||
if position != "" {
|
||||
fields := strings.Fields(position)
|
||||
marketPosition := strings.Trim(accountPositionMap[key].MarketPosition, " ")
|
||||
if marketPosition != "" {
|
||||
fields := strings.Fields(marketPosition)
|
||||
account.MarketNumber = fields[0]
|
||||
account.MarketCurrency = fields[1]
|
||||
account.MarketCurrencySymbol = script.GetCommoditySymbol(fields[1])
|
||||
}
|
||||
position := strings.Trim(accountPositionMap[key].Position, " ")
|
||||
if position != "" {
|
||||
account.Positions = parseAccountPositions(position)
|
||||
}
|
||||
result = append(result, account)
|
||||
}
|
||||
OK(c, result)
|
||||
}
|
||||
|
||||
func parseAccountPositions(input string) []script.AccountPosition {
|
||||
// 使用正则表达式提取数字、货币代码和金额
|
||||
re := regexp.MustCompile(`(-?\d+\.\d+) (\w+)`)
|
||||
matches := re.FindAllStringSubmatch(input, -1)
|
||||
|
||||
var positions []script.AccountPosition
|
||||
|
||||
// 遍历匹配项并创建 AccountPosition
|
||||
for _, match := range matches {
|
||||
number := match[1]
|
||||
currency := match[2]
|
||||
|
||||
// 获取货币符号
|
||||
symbol := script.GetCommoditySymbol(currency)
|
||||
|
||||
// 创建 AccountPosition
|
||||
position := script.AccountPosition{
|
||||
Number: number,
|
||||
Currency: currency,
|
||||
CurrencySymbol: symbol,
|
||||
}
|
||||
|
||||
// 添加到切片中
|
||||
positions = append(positions, position)
|
||||
}
|
||||
|
||||
return positions
|
||||
}
|
||||
|
||||
func QueryAccountType(c *gin.Context) {
|
||||
ledgerConfig := script.GetLedgerConfigFromContext(c)
|
||||
accountTypes := script.GetLedgerAccountTypes(ledgerConfig.Id)
|
||||
|
|
|
|||
|
|
@ -171,11 +171,16 @@ func saveTransaction(c *gin.Context, addTransactionForm AddTransactionForm, ledg
|
|||
} else {
|
||||
line += fmt.Sprintf("\r\n %s %s %s", entry.Account, entry.Number.Round(2).StringFixedBank(2), account.Currency)
|
||||
}
|
||||
zero := decimal.NewFromInt(0)
|
||||
// 判断是否涉及多币种的转换
|
||||
if account.Currency != ledgerConfig.OperatingCurrency && entry.Account != ledgerConfig.OpeningBalances {
|
||||
autoBalance = true
|
||||
autoBalance = false
|
||||
// 汇率值小于等于0,则不进行汇率转换
|
||||
if entry.Price.LessThanOrEqual(zero) {
|
||||
continue
|
||||
}
|
||||
// 根据 number 的正负来判断是买入还是卖出
|
||||
if entry.Number.GreaterThan(decimal.NewFromInt(0)) {
|
||||
if entry.Number.GreaterThan(zero) {
|
||||
// {351.729 CNY, 2021-09-29}
|
||||
line += fmt.Sprintf(" {%s %s, %s}", entry.Price, ledgerConfig.OperatingCurrency, addTransactionForm.Date)
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Reference in New Issue