beancount-gs/service/ledger.go

287 lines
8.0 KiB
Go
Raw Permalink Normal View History

2021-11-18 08:27:28 +00:00
package service
import (
"crypto/sha1"
"encoding/hex"
"io"
"io/ioutil"
2022-03-11 15:18:38 +00:00
"os"
2021-11-29 16:13:41 +00:00
"os/exec"
2021-12-04 05:12:12 +00:00
"sort"
2021-11-18 08:27:28 +00:00
"strings"
2021-12-04 05:12:12 +00:00
"time"
2022-03-11 15:18:38 +00:00
"github.com/beancount-gs/script"
"github.com/gin-gonic/gin"
2021-11-18 08:27:28 +00:00
)
2021-11-29 16:13:41 +00:00
func CheckBeancount(c *gin.Context) {
cmd := exec.Command("bean-query", "--version")
output, err := cmd.Output()
if err != nil {
InternalError(c, err.Error())
return
}
OK(c, string(output))
}
func QueryServerConfig(c *gin.Context) {
OK(c, script.GetServerConfig())
}
2021-12-04 05:12:12 +00:00
type QueryLedgerResult struct {
Mail string `json:"mail"`
Title string `json:"title"`
CreateDate string `json:"createDate"`
OperatingCurrency string `json:"operatingCurrency"`
}
type LedgerSort []QueryLedgerResult
func (s LedgerSort) Len() int {
return len(s)
}
func (s LedgerSort) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}
func (s LedgerSort) Less(i, j int) bool {
return s[i].CreateDate <= s[j].CreateDate && s[i].Mail <= s[j].Mail
}
func QueryLedgerList(c *gin.Context) {
result := make([]QueryLedgerResult, 0)
for _, config := range script.GetLedgerConfigMap() {
result = append(result, QueryLedgerResult{
Title: config.Title,
Mail: config.Mail,
CreateDate: config.CreateDate,
OperatingCurrency: config.OperatingCurrency,
})
}
sort.Sort(LedgerSort(result))
OK(c, result)
}
2021-12-01 09:32:15 +00:00
type UpdateConfigForm struct {
2021-12-04 04:06:45 +00:00
Secret string `form:"secret" binding:"required"`
2021-12-01 09:32:15 +00:00
StartDate string `form:"startDate" binding:"required"`
DataPath string `form:"dataPath" binding:"required"`
OperatingCurrency string `form:"operatingCurrency" binding:"required"`
OpeningBalances string `form:"openingBalances" binding:"required"`
IsBak bool `form:"isBak" binding:"required"`
}
2021-11-29 16:13:41 +00:00
2021-12-01 09:32:15 +00:00
func UpdateServerConfig(c *gin.Context) {
var updateConfigForm UpdateConfigForm
if err := c.ShouldBindJSON(&updateConfigForm); err != nil {
BadRequest(c, err.Error())
return
}
2021-12-04 04:06:45 +00:00
if !script.EqualServerSecret(updateConfigForm.Secret) {
ServerSecretNotMatch(c)
return
}
2021-12-01 09:32:15 +00:00
var serverConfig = script.Config{
OperatingCurrency: updateConfigForm.OperatingCurrency,
DataPath: updateConfigForm.DataPath,
StartDate: updateConfigForm.StartDate,
OpeningBalances: updateConfigForm.OpeningBalances,
IsBak: updateConfigForm.IsBak,
}
// 更新配置
err := script.UpdateServerConfig(serverConfig)
if err != nil {
InternalError(c, err.Error())
return
}
// 账本目录不存在,则创建
dataPath := serverConfig.DataPath
if !script.FileIfExist(dataPath) {
err = script.MkDir(dataPath)
if err != nil {
InternalError(c, err.Error())
return
}
}
// 加载账户缓存
err = script.LoadLedgerConfigMap()
if err != nil {
InternalError(c, err.Error())
return
}
err = script.LoadLedgerAccountsMap()
if err != nil {
InternalError(c, err.Error())
return
}
QueryServerConfig(c)
2021-11-29 16:13:41 +00:00
}
2021-11-18 08:27:28 +00:00
type LoginForm struct {
2021-12-01 09:32:15 +00:00
LedgerName string `form:"ledgerName" binding:"required"`
Secret string `form:"secret"`
OperatingCurrency string `form:"operatingCurrency"`
StartDate string `form:"startDate"`
OpeningBalances string `form:"openingBalances"`
IsBak bool `form:"isBak"`
2021-11-18 08:27:28 +00:00
}
func OpenOrCreateLedger(c *gin.Context) {
var loginForm LoginForm
if err := c.ShouldBindJSON(&loginForm); err != nil {
BadRequest(c, err.Error())
return
}
// is mail exist white list
2021-12-01 09:32:15 +00:00
if !script.IsInWhiteList(loginForm.LedgerName) {
2021-11-18 08:27:28 +00:00
LedgerIsNotExist(c)
return
}
t := sha1.New()
2021-12-01 09:32:15 +00:00
_, err := io.WriteString(t, loginForm.LedgerName+loginForm.Secret)
2021-11-18 08:27:28 +00:00
if err != nil {
LedgerIsNotAllowAccess(c)
return
}
ledgerId := hex.EncodeToString(t.Sum(nil))
2021-12-01 09:32:15 +00:00
userLedger := script.GetLedgerConfigByMail(loginForm.LedgerName)
2021-11-18 08:27:28 +00:00
if userLedger != nil {
if ledgerId != userLedger.Id {
LedgerIsNotAllowAccess(c)
return
}
2021-12-01 09:32:15 +00:00
// 账本已存在,返回账本信息
resultMap := make(map[string]string)
resultMap["ledgerId"] = ledgerId
resultMap["title"] = userLedger.Title
resultMap["currency"] = userLedger.OperatingCurrency
resultMap["currencySymbol"] = script.GetCommoditySymbol(userLedger.OperatingCurrency)
2021-12-04 05:12:12 +00:00
resultMap["createDate"] = userLedger.CreateDate
2021-12-01 09:32:15 +00:00
OK(c, resultMap)
return
2021-11-18 08:27:28 +00:00
}
2021-12-01 09:32:15 +00:00
userLedger, err = createNewLedger(loginForm, ledgerId)
if err != nil {
InternalError(c, err.Error())
return
}
resultMap := make(map[string]string)
resultMap["ledgerId"] = ledgerId
resultMap["title"] = userLedger.Title
resultMap["currency"] = userLedger.OperatingCurrency
resultMap["currencySymbol"] = script.GetCommoditySymbol(userLedger.OperatingCurrency)
2021-12-04 05:12:12 +00:00
resultMap["createDate"] = userLedger.CreateDate
2021-12-01 09:32:15 +00:00
OK(c, resultMap)
}
2022-03-11 15:18:38 +00:00
func DeleteLedger(c *gin.Context) {
ledgerConfig := script.GetLedgerConfigFromContext(c)
2022-03-19 08:18:27 +00:00
// remove from ledger_config.json
2022-03-11 15:18:38 +00:00
ledgerConfigMap := script.GetLedgerConfigMap()
delete(ledgerConfigMap, ledgerConfig.Id)
2022-03-19 08:18:27 +00:00
err := script.WriteLedgerConfigMap(ledgerConfigMap)
2022-03-11 15:18:38 +00:00
if err != nil {
InternalError(c, "Failed to update ledger_config.json")
return
}
// remove from account cache
script.ClearLedgerAccounts(ledgerConfig.Id)
script.LogInfo(ledgerConfig.Mail, "Success clear ledger account cache "+ledgerConfig.Id)
// remove from account types cache
script.ClearLedgerAccountTypes(ledgerConfig.Id)
script.LogInfo(ledgerConfig.Mail, "Success clear ledger account types cache "+ledgerConfig.Id)
2022-03-19 08:18:27 +00:00
// delete source file
err = os.RemoveAll(ledgerConfig.DataPath)
if err != nil {
script.LogError(ledgerConfig.Mail, "Failed to delete ledger, cause by "+err.Error())
InternalError(c, "Failed to delete ledger")
return
}
script.LogInfo(ledgerConfig.Mail, "Success delete "+ledgerConfig.DataPath)
2022-03-11 15:18:38 +00:00
OK(c, "OK")
}
2021-12-01 09:32:15 +00:00
func createNewLedger(loginForm LoginForm, ledgerId string) (*script.Config, error) {
2021-11-18 08:27:28 +00:00
// create new ledger
serverConfig := script.GetServerConfig()
ledgerConfigMap := script.GetLedgerConfigMap()
2021-12-01 09:32:15 +00:00
currency := loginForm.OperatingCurrency
if currency == "" {
currency = serverConfig.OperatingCurrency
}
startDate := loginForm.StartDate
if startDate == "" {
startDate = serverConfig.StartDate
}
openingBalances := loginForm.OpeningBalances
if openingBalances == "" {
openingBalances = serverConfig.OpeningBalances
}
2021-11-18 08:27:28 +00:00
ledgerConfig := script.Config{
Id: ledgerId,
2021-12-01 09:32:15 +00:00
Mail: loginForm.LedgerName,
Title: loginForm.LedgerName,
2021-11-18 08:27:28 +00:00
DataPath: serverConfig.DataPath + "/" + ledgerId,
2021-12-01 09:32:15 +00:00
OperatingCurrency: currency,
StartDate: startDate,
OpeningBalances: openingBalances,
IsBak: loginForm.IsBak,
2021-12-04 05:12:12 +00:00
CreateDate: time.Now().Format("2006-01-02"),
2021-11-18 08:27:28 +00:00
}
// init ledger files
2021-12-01 09:32:15 +00:00
err := initLedgerFiles(script.GetTemplateLedgerConfigDirPath(), ledgerConfig.DataPath, ledgerConfig)
2021-11-18 08:27:28 +00:00
if err != nil {
2021-12-01 09:32:15 +00:00
return nil, err
2021-11-18 08:27:28 +00:00
}
// add ledger config to ledger_config.json
ledgerConfigMap[ledgerId] = ledgerConfig
err = script.WriteLedgerConfigMap(ledgerConfigMap)
if err != nil {
2021-12-01 09:32:15 +00:00
return nil, err
}
// add accounts cache
err = script.LoadLedgerAccounts(ledgerId)
if err != nil {
return nil, err
2021-11-18 08:27:28 +00:00
}
2021-12-01 09:32:15 +00:00
return &ledgerConfig, nil
2021-11-18 08:27:28 +00:00
}
2021-11-19 09:54:02 +00:00
func initLedgerFiles(sourceFilePath string, targetFilePath string, ledgerConfig script.Config) error {
return copyFile(sourceFilePath, targetFilePath, ledgerConfig)
2021-11-18 08:27:28 +00:00
}
2021-11-19 09:54:02 +00:00
func copyFile(sourceFilePath string, targetFilePath string, ledgerConfig script.Config) error {
2021-11-18 08:27:28 +00:00
rd, err := ioutil.ReadDir(sourceFilePath)
if err != nil {
return err
}
for _, fi := range rd {
newSourceFilePath := sourceFilePath + "/" + fi.Name()
newTargetFilePath := targetFilePath + "/" + fi.Name()
if fi.IsDir() {
err = script.MkDir(newTargetFilePath)
2021-11-19 09:54:02 +00:00
err = copyFile(newSourceFilePath, newTargetFilePath, ledgerConfig)
} else if !script.FileIfExist(newTargetFilePath) {
2021-11-18 08:27:28 +00:00
fileContent, err := script.ReadFile(newSourceFilePath)
if err != nil {
return err
}
2021-11-19 09:54:02 +00:00
err = script.WriteFile(newTargetFilePath, strings.ReplaceAll(strings.ReplaceAll(string(fileContent), "%startDate%", ledgerConfig.StartDate), "%operatingCurrency%", ledgerConfig.OperatingCurrency))
2021-11-29 16:13:41 +00:00
script.LogInfo(ledgerConfig.Mail, "Success create file "+newTargetFilePath)
2021-11-18 08:27:28 +00:00
}
if err != nil {
return err
}
}
return nil
}