support user custom exchange rates data
This commit is contained in:
+25
-16
@@ -20,14 +20,15 @@ const pageCountForDataExport = 1000
|
||||
// DataManagementsApi represents data management api
|
||||
type DataManagementsApi struct {
|
||||
ApiUsingConfig
|
||||
tokens *services.TokenService
|
||||
users *services.UserService
|
||||
accounts *services.AccountService
|
||||
transactions *services.TransactionService
|
||||
categories *services.TransactionCategoryService
|
||||
tags *services.TransactionTagService
|
||||
pictures *services.TransactionPictureService
|
||||
templates *services.TransactionTemplateService
|
||||
tokens *services.TokenService
|
||||
users *services.UserService
|
||||
accounts *services.AccountService
|
||||
transactions *services.TransactionService
|
||||
categories *services.TransactionCategoryService
|
||||
tags *services.TransactionTagService
|
||||
pictures *services.TransactionPictureService
|
||||
templates *services.TransactionTemplateService
|
||||
userCustomExchangeRates *services.UserCustomExchangeRatesService
|
||||
}
|
||||
|
||||
// Initialize a data management api singleton instance
|
||||
@@ -36,14 +37,15 @@ var (
|
||||
ApiUsingConfig: ApiUsingConfig{
|
||||
container: settings.Container,
|
||||
},
|
||||
tokens: services.Tokens,
|
||||
users: services.Users,
|
||||
accounts: services.Accounts,
|
||||
transactions: services.Transactions,
|
||||
categories: services.TransactionCategories,
|
||||
tags: services.TransactionTags,
|
||||
pictures: services.TransactionPictures,
|
||||
templates: services.TransactionTemplates,
|
||||
tokens: services.Tokens,
|
||||
users: services.Users,
|
||||
accounts: services.Accounts,
|
||||
transactions: services.Transactions,
|
||||
categories: services.TransactionCategories,
|
||||
tags: services.TransactionTags,
|
||||
pictures: services.TransactionPictures,
|
||||
templates: services.TransactionTemplates,
|
||||
userCustomExchangeRates: services.UserCustomExchangeRates,
|
||||
}
|
||||
)
|
||||
|
||||
@@ -179,6 +181,13 @@ func (a *DataManagementsApi) ClearDataHandler(c *core.WebContext) (any, *errs.Er
|
||||
return nil, errs.Or(err, errs.ErrOperationFailed)
|
||||
}
|
||||
|
||||
err = a.userCustomExchangeRates.DeleteAllCustomExchangeRates(c, uid)
|
||||
|
||||
if err != nil {
|
||||
log.Errorf(c, "[data_managements.ClearDataHandler] failed to delete all user custom exchange rates, because %s", err.Error())
|
||||
return nil, errs.Or(err, errs.ErrOperationFailed)
|
||||
}
|
||||
|
||||
log.Infof(c, "[data_managements.ClearDataHandler] user \"uid:%d\" has cleared all data", uid)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
@@ -4,12 +4,17 @@ import (
|
||||
"github.com/mayswind/ezbookkeeping/pkg/core"
|
||||
"github.com/mayswind/ezbookkeeping/pkg/errs"
|
||||
"github.com/mayswind/ezbookkeeping/pkg/exchangerates"
|
||||
"github.com/mayswind/ezbookkeeping/pkg/log"
|
||||
"github.com/mayswind/ezbookkeeping/pkg/models"
|
||||
"github.com/mayswind/ezbookkeeping/pkg/services"
|
||||
"github.com/mayswind/ezbookkeeping/pkg/settings"
|
||||
)
|
||||
|
||||
// ExchangeRatesApi represents exchange rate api
|
||||
type ExchangeRatesApi struct {
|
||||
ApiUsingConfig
|
||||
users *services.UserService
|
||||
userCustomExchangeRates *services.UserCustomExchangeRatesService
|
||||
}
|
||||
|
||||
// Initialize a exchange rate api singleton instance
|
||||
@@ -18,6 +23,8 @@ var (
|
||||
ApiUsingConfig: ApiUsingConfig{
|
||||
container: settings.Container,
|
||||
},
|
||||
users: services.Users,
|
||||
userCustomExchangeRates: services.UserCustomExchangeRates,
|
||||
}
|
||||
)
|
||||
|
||||
@@ -37,3 +44,69 @@ func (a *ExchangeRatesApi) LatestExchangeRateHandler(c *core.WebContext) (any, *
|
||||
|
||||
return exchangeRateResponse, nil
|
||||
}
|
||||
|
||||
// UserCustomExchangeRateUpdateHandler updates user custom exchange rates data by request parameters for current user
|
||||
func (a *ExchangeRatesApi) UserCustomExchangeRateUpdateHandler(c *core.WebContext) (any, *errs.Error) {
|
||||
var customExchangeRateUpdateReq models.UserCustomExchangeRateUpdateRequest
|
||||
err := c.ShouldBindJSON(&customExchangeRateUpdateReq)
|
||||
|
||||
if err != nil {
|
||||
log.Warnf(c, "[exchange_rates.UserCustomExchangeRateUpdateHandler] parse request failed, because %s", err.Error())
|
||||
return nil, errs.NewIncompleteOrIncorrectSubmissionError(err)
|
||||
}
|
||||
|
||||
uid := c.GetCurrentUid()
|
||||
user, err := a.users.GetUserById(c, uid)
|
||||
|
||||
if err != nil {
|
||||
log.Errorf(c, "[exchange_rates.UserCustomExchangeRateUpdateHandler] failed to get user \"uid:%d\", because %s", uid, err.Error())
|
||||
return nil, errs.Or(err, errs.ErrOperationFailed)
|
||||
}
|
||||
|
||||
if customExchangeRateUpdateReq.Currency == user.DefaultCurrency {
|
||||
return nil, errs.ErrCannotUpdateExchangeRateForDefaultCurrency
|
||||
}
|
||||
|
||||
newCustomExchangeRate, defaultCurrencyExchangeRate, err := a.userCustomExchangeRates.UpdateCustomExchangeRate(c, uid, customExchangeRateUpdateReq.Currency, customExchangeRateUpdateReq.Rate, user.DefaultCurrency)
|
||||
|
||||
if err != nil {
|
||||
log.Errorf(c, "[exchange_rates.UserCustomExchangeRateUpdateHandler] failed to update user custom exchange rate \"currency:%s\" for user \"uid:%d\", because %s", customExchangeRateUpdateReq.Currency, uid, err.Error())
|
||||
return nil, errs.Or(err, errs.ErrOperationFailed)
|
||||
}
|
||||
|
||||
log.Infof(c, "[exchange_rates.UserCustomExchangeRateUpdateHandler] user \"uid:%d\" has updated user custom exchange rate \"currency:%s\" successfully", uid, customExchangeRateUpdateReq.Currency)
|
||||
return newCustomExchangeRate.ToUserCustomExchangeRateUpdateResponse(defaultCurrencyExchangeRate.Rate), nil
|
||||
}
|
||||
|
||||
// UserCustomExchangeRateDeleteHandler deletes an existed user custom exchange rates data by request parameters for current user
|
||||
func (a *ExchangeRatesApi) UserCustomExchangeRateDeleteHandler(c *core.WebContext) (any, *errs.Error) {
|
||||
var customExchangeRateDeleteReq models.UserCustomExchangeRateDeleteRequest
|
||||
err := c.ShouldBindJSON(&customExchangeRateDeleteReq)
|
||||
|
||||
if err != nil {
|
||||
log.Warnf(c, "[exchange_rates.UserCustomExchangeRateDeleteHandler] parse request failed, because %s", err.Error())
|
||||
return nil, errs.NewIncompleteOrIncorrectSubmissionError(err)
|
||||
}
|
||||
|
||||
uid := c.GetCurrentUid()
|
||||
user, err := a.users.GetUserById(c, uid)
|
||||
|
||||
if err != nil {
|
||||
log.Errorf(c, "[exchange_rates.UserCustomExchangeRateDeleteHandler] failed to get user \"uid:%d\", because %s", uid, err.Error())
|
||||
return nil, errs.Or(err, errs.ErrOperationFailed)
|
||||
}
|
||||
|
||||
if customExchangeRateDeleteReq.Currency == user.DefaultCurrency {
|
||||
return nil, errs.ErrCannotDeleteExchangeRateForDefaultCurrency
|
||||
}
|
||||
|
||||
err = a.userCustomExchangeRates.DeleteCustomExchangeRate(c, uid, customExchangeRateDeleteReq.Currency)
|
||||
|
||||
if err != nil {
|
||||
log.Errorf(c, "[exchange_rates.UserCustomExchangeRateDeleteHandler] failed to delete user custom exchange rate \"currency:%s\" for user \"uid:%d\", because %s", customExchangeRateDeleteReq.Currency, uid, err.Error())
|
||||
return nil, errs.Or(err, errs.ErrOperationFailed)
|
||||
}
|
||||
|
||||
log.Infof(c, "[exchange_rates.UserCustomExchangeRateDeleteHandler] user \"uid:%d\" has deleted user custom exchange rate \"currency:%s\"", uid, customExchangeRateDeleteReq.Currency)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
+14
-13
@@ -25,19 +25,20 @@ const (
|
||||
|
||||
// Sub categories of normal error
|
||||
const (
|
||||
NormalSubcategoryGlobal = 0
|
||||
NormalSubcategoryUser = 1
|
||||
NormalSubcategoryToken = 2
|
||||
NormalSubcategoryTwofactor = 3
|
||||
NormalSubcategoryAccount = 4
|
||||
NormalSubcategoryTransaction = 5
|
||||
NormalSubcategoryCategory = 6
|
||||
NormalSubcategoryTag = 7
|
||||
NormalSubcategoryDataManagement = 8
|
||||
NormalSubcategoryMapProxy = 9
|
||||
NormalSubcategoryTemplate = 10
|
||||
NormalSubcategoryPicture = 11
|
||||
NormalSubcategoryConverter = 12
|
||||
NormalSubcategoryGlobal = 0
|
||||
NormalSubcategoryUser = 1
|
||||
NormalSubcategoryToken = 2
|
||||
NormalSubcategoryTwofactor = 3
|
||||
NormalSubcategoryAccount = 4
|
||||
NormalSubcategoryTransaction = 5
|
||||
NormalSubcategoryCategory = 6
|
||||
NormalSubcategoryTag = 7
|
||||
NormalSubcategoryDataManagement = 8
|
||||
NormalSubcategoryMapProxy = 9
|
||||
NormalSubcategoryTemplate = 10
|
||||
NormalSubcategoryPicture = 11
|
||||
NormalSubcategoryConverter = 12
|
||||
NormalSubcategoryUserCustomExchangeRate = 13
|
||||
)
|
||||
|
||||
// Error represents the specific error returned to user
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package errs
|
||||
|
||||
import "net/http"
|
||||
|
||||
// Error codes related to user custom exchange rates
|
||||
var (
|
||||
ErrUserCustomExchangeRateNotFound = NewNormalError(NormalSubcategoryUserCustomExchangeRate, 0, http.StatusBadRequest, "user custom exchange rate data not found")
|
||||
ErrCannotUpdateExchangeRateForDefaultCurrency = NewNormalError(NormalSubcategoryUserCustomExchangeRate, 1, http.StatusBadRequest, "cannot update exchange rate data for base currency")
|
||||
ErrCannotDeleteExchangeRateForDefaultCurrency = NewNormalError(NormalSubcategoryUserCustomExchangeRate, 2, http.StatusBadRequest, "cannot delete exchange rate data for base currency")
|
||||
)
|
||||
@@ -68,6 +68,9 @@ func InitializeExchangeRatesDataSource(config *settings.Config) error {
|
||||
} else if config.ExchangeRatesDataSource == settings.InternationalMonetaryFundDataSource {
|
||||
Container.Current = newCommonHttpExchangeRatesDataSource(&InternationalMonetaryFundDataSource{})
|
||||
return nil
|
||||
} else if config.ExchangeRatesDataSource == settings.UserCustomExchangeRatesDataSource {
|
||||
Container.Current = newUserCustomExchangeRatesDataSource()
|
||||
return nil
|
||||
}
|
||||
|
||||
return errs.ErrInvalidExchangeRatesDataSource
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
package exchangerates
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"github.com/mayswind/ezbookkeeping/pkg/core"
|
||||
"github.com/mayswind/ezbookkeeping/pkg/errs"
|
||||
"github.com/mayswind/ezbookkeeping/pkg/log"
|
||||
"github.com/mayswind/ezbookkeeping/pkg/models"
|
||||
"github.com/mayswind/ezbookkeeping/pkg/services"
|
||||
"github.com/mayswind/ezbookkeeping/pkg/settings"
|
||||
"github.com/mayswind/ezbookkeeping/pkg/validators"
|
||||
)
|
||||
|
||||
const userDataSourceType = "user_custom"
|
||||
|
||||
// UserCustomExchangeRatesDataSource defines the structure of user custom exchange rates data source
|
||||
type UserCustomExchangeRatesDataSource struct {
|
||||
ExchangeRatesDataSource
|
||||
users *services.UserService
|
||||
userCustomExchangeRates *services.UserCustomExchangeRatesService
|
||||
}
|
||||
|
||||
func (e *UserCustomExchangeRatesDataSource) GetLatestExchangeRates(c core.Context, uid int64, currentConfig *settings.Config) (*models.LatestExchangeRateResponse, error) {
|
||||
user, err := e.users.GetUserById(c, uid)
|
||||
|
||||
if err != nil {
|
||||
log.Errorf(c, "[user_custom_datasource.GetLatestExchangeRates] failed to get user \"uid:%d\", because %s", uid, err.Error())
|
||||
return nil, errs.Or(err, errs.ErrOperationFailed)
|
||||
}
|
||||
|
||||
customExchangeRates, err := e.userCustomExchangeRates.GetAllCustomExchangeRatesByUid(c, uid)
|
||||
|
||||
if err != nil {
|
||||
log.Errorf(c, "[user_custom_datasource.GetLatestExchangeRates] failed to get user custom exchange rates for user \"uid:%d\", because %s", uid, err.Error())
|
||||
return nil, errs.Or(err, errs.ErrOperationFailed)
|
||||
}
|
||||
|
||||
baseCurrencyRate := int64(0)
|
||||
hasDefaultCurrencyRate := false
|
||||
|
||||
for i := 0; i < len(customExchangeRates); i++ {
|
||||
customExchangeRate := customExchangeRates[i]
|
||||
|
||||
if customExchangeRate.Currency == user.DefaultCurrency {
|
||||
baseCurrencyRate = customExchangeRate.Rate
|
||||
hasDefaultCurrencyRate = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
allExchangeRates := make(models.LatestExchangeRateSlice, 0, len(customExchangeRates))
|
||||
latestUpdateTime := int64(0)
|
||||
|
||||
for i := 0; i < len(customExchangeRates); i++ {
|
||||
customExchangeRate := customExchangeRates[i]
|
||||
|
||||
if _, exists := validators.AllCurrencyNames[customExchangeRate.Currency]; !exists {
|
||||
continue
|
||||
}
|
||||
|
||||
if customExchangeRate.UpdatedUnixTime > latestUpdateTime {
|
||||
latestUpdateTime = customExchangeRate.UpdatedUnixTime
|
||||
}
|
||||
|
||||
if hasDefaultCurrencyRate && baseCurrencyRate > 0 {
|
||||
allExchangeRates = append(allExchangeRates, customExchangeRate.ToLatestExchangeRate(baseCurrencyRate))
|
||||
}
|
||||
}
|
||||
|
||||
sort.Sort(allExchangeRates)
|
||||
|
||||
if latestUpdateTime < 1 {
|
||||
latestUpdateTime = time.Now().Unix()
|
||||
}
|
||||
|
||||
if !hasDefaultCurrencyRate {
|
||||
allExchangeRates = append(allExchangeRates, &models.LatestExchangeRate{
|
||||
Currency: user.DefaultCurrency,
|
||||
Rate: "1",
|
||||
})
|
||||
}
|
||||
|
||||
finalExchangeRateResponse := &models.LatestExchangeRateResponse{
|
||||
DataSource: userDataSourceType,
|
||||
ReferenceUrl: "",
|
||||
UpdateTime: latestUpdateTime,
|
||||
BaseCurrency: user.DefaultCurrency,
|
||||
ExchangeRates: allExchangeRates,
|
||||
}
|
||||
|
||||
return finalExchangeRateResponse, nil
|
||||
}
|
||||
|
||||
func newUserCustomExchangeRatesDataSource() *UserCustomExchangeRatesDataSource {
|
||||
return &UserCustomExchangeRatesDataSource{
|
||||
users: services.Users,
|
||||
userCustomExchangeRates: services.UserCustomExchangeRates,
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,39 @@
|
||||
package models
|
||||
|
||||
import "strings"
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/mayswind/ezbookkeeping/pkg/utils"
|
||||
)
|
||||
|
||||
const UserCustomExchangeRateFactorInDatabase = int64(100000000)
|
||||
|
||||
// UserCustomExchangeRate represents user custom exchange rate data
|
||||
type UserCustomExchangeRate struct {
|
||||
Uid int64 `xorm:"PK NOT NULL"`
|
||||
DeletedUnixTime int64 `xorm:"PK NOT NULL"`
|
||||
Currency string `xorm:"PK VARCHAR(3) NOT NULL"`
|
||||
Rate int64 `xorm:"NOT NULL"`
|
||||
CreatedUnixTime int64
|
||||
UpdatedUnixTime int64
|
||||
}
|
||||
|
||||
// UserCustomExchangeRateUpdateRequest represents all parameters of user custom exchange rate data updating request
|
||||
type UserCustomExchangeRateUpdateRequest struct {
|
||||
Currency string `json:"currency" binding:"required,len=3,validCurrency"`
|
||||
Rate string `json:"rate"`
|
||||
}
|
||||
|
||||
// UserCustomExchangeRateDeleteRequest represents all parameters of user custom exchange rate data deleting request
|
||||
type UserCustomExchangeRateDeleteRequest struct {
|
||||
Currency string `json:"currency" binding:"required,len=3,validCurrency"`
|
||||
}
|
||||
|
||||
// UserCustomExchangeRateUpdateResponse represents a view-object of the result of updating user custom exchange rate data
|
||||
type UserCustomExchangeRateUpdateResponse struct {
|
||||
LatestExchangeRate
|
||||
UpdateTime int64 `json:"updateTime"`
|
||||
}
|
||||
|
||||
// LatestExchangeRateResponse returns a view-object which contains latest exchange rate
|
||||
type LatestExchangeRateResponse struct {
|
||||
@@ -17,6 +50,53 @@ type LatestExchangeRate struct {
|
||||
Rate string `json:"rate"`
|
||||
}
|
||||
|
||||
// ToLatestExchangeRate returns a data pair of currency and exchange rate according to database model
|
||||
func (r *UserCustomExchangeRate) ToLatestExchangeRate(baseCurrencyRate int64) *LatestExchangeRate {
|
||||
rate := float64(0)
|
||||
|
||||
if baseCurrencyRate > 0 {
|
||||
rate = float64(r.Rate) / float64(baseCurrencyRate)
|
||||
}
|
||||
|
||||
return &LatestExchangeRate{
|
||||
Currency: r.Currency,
|
||||
Rate: utils.Float64ToString(rate),
|
||||
}
|
||||
}
|
||||
|
||||
// ToUserCustomExchangeRateUpdateResponse returns a view-object of the result of updating user custom exchange rate data according to database model
|
||||
func (r *UserCustomExchangeRate) ToUserCustomExchangeRateUpdateResponse(baseCurrencyRate int64) *UserCustomExchangeRateUpdateResponse {
|
||||
return &UserCustomExchangeRateUpdateResponse{
|
||||
LatestExchangeRate: *r.ToLatestExchangeRate(baseCurrencyRate),
|
||||
UpdateTime: r.UpdatedUnixTime,
|
||||
}
|
||||
}
|
||||
|
||||
// CreateUserCustomExchangeRate returns a user custom exchange rate database model according to currency and rate
|
||||
func CreateUserCustomExchangeRate(uid int64, currency string, exchangeRate string, baseCurrencyRate int64) (*UserCustomExchangeRate, error) {
|
||||
if baseCurrencyRate <= 0 {
|
||||
return &UserCustomExchangeRate{
|
||||
Uid: uid,
|
||||
Currency: currency,
|
||||
Rate: UserCustomExchangeRateFactorInDatabase,
|
||||
}, nil
|
||||
}
|
||||
|
||||
rate, err := utils.StringToFloat64(exchangeRate)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rate = rate * float64(baseCurrencyRate)
|
||||
|
||||
return &UserCustomExchangeRate{
|
||||
Uid: uid,
|
||||
Currency: currency,
|
||||
Rate: int64(rate),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// LatestExchangeRateSlice represents the slice data structure of LatestExchangeRate
|
||||
type LatestExchangeRateSlice []*LatestExchangeRate
|
||||
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"time"
|
||||
"xorm.io/xorm"
|
||||
|
||||
"github.com/mayswind/ezbookkeeping/pkg/core"
|
||||
"github.com/mayswind/ezbookkeeping/pkg/datastore"
|
||||
"github.com/mayswind/ezbookkeeping/pkg/errs"
|
||||
"github.com/mayswind/ezbookkeeping/pkg/models"
|
||||
)
|
||||
|
||||
// UserCustomExchangeRatesService represents user custom exchange rate data service
|
||||
type UserCustomExchangeRatesService struct {
|
||||
ServiceUsingDB
|
||||
}
|
||||
|
||||
// Initialize a user custom exchange rate data service singleton instance
|
||||
var (
|
||||
UserCustomExchangeRates = &UserCustomExchangeRatesService{
|
||||
ServiceUsingDB: ServiceUsingDB{
|
||||
container: datastore.Container,
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
// GetAllCustomExchangeRatesByUid returns all user exchange rate data models of user
|
||||
func (s *UserCustomExchangeRatesService) GetAllCustomExchangeRatesByUid(c core.Context, uid int64) ([]*models.UserCustomExchangeRate, error) {
|
||||
if uid <= 0 {
|
||||
return nil, errs.ErrUserIdInvalid
|
||||
}
|
||||
|
||||
var customExchangeRates []*models.UserCustomExchangeRate
|
||||
err := s.UserDataDB(uid).NewSession(c).Where("uid=? AND deleted_unix_time=?", uid, 0).Find(&customExchangeRates)
|
||||
|
||||
return customExchangeRates, err
|
||||
}
|
||||
|
||||
// UpdateCustomExchangeRate updates user exchange rate data model to database
|
||||
func (s *UserCustomExchangeRatesService) UpdateCustomExchangeRate(c core.Context, uid int64, currency string, rate string, defaultCurrency string) (*models.UserCustomExchangeRate, *models.UserCustomExchangeRate, error) {
|
||||
if uid <= 0 {
|
||||
return nil, nil, errs.ErrUserIdInvalid
|
||||
}
|
||||
|
||||
now := time.Now().Unix()
|
||||
newCustomExchangeRate := &models.UserCustomExchangeRate{}
|
||||
defaultCurrencyExchangeRate := &models.UserCustomExchangeRate{}
|
||||
|
||||
err := s.UserDataDB(uid).DoTransaction(c, func(sess *xorm.Session) error {
|
||||
oldCustomExchangeRate := &models.UserCustomExchangeRate{}
|
||||
has, err := sess.Where("uid=? AND deleted_unix_time=? AND currency=?", uid, 0, currency).Get(oldCustomExchangeRate)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if has {
|
||||
updateOldExchangeRateModel := &models.UserCustomExchangeRate{
|
||||
DeletedUnixTime: now,
|
||||
}
|
||||
|
||||
_, err = sess.Cols("deleted_unix_time").Where("uid=? AND deleted_unix_time=? AND currency=?", uid, 0, currency).Update(updateOldExchangeRateModel)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if currency != defaultCurrency {
|
||||
has, err := sess.Where("uid=? AND deleted_unix_time=? AND currency=?", uid, 0, defaultCurrency).Get(defaultCurrencyExchangeRate)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !has {
|
||||
defaultCurrencyExchangeRate, _ = models.CreateUserCustomExchangeRate(uid, defaultCurrency, "1", 0)
|
||||
defaultCurrencyExchangeRate.CreatedUnixTime = now
|
||||
defaultCurrencyExchangeRate.UpdatedUnixTime = now
|
||||
defaultCurrencyExchangeRate.DeletedUnixTime = 0
|
||||
_, err = sess.Insert(defaultCurrencyExchangeRate)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
defaultCurrencyExchangeRate = oldCustomExchangeRate
|
||||
}
|
||||
|
||||
newCustomExchangeRate, err = models.CreateUserCustomExchangeRate(uid, currency, rate, defaultCurrencyExchangeRate.Rate)
|
||||
newCustomExchangeRate.CreatedUnixTime = now
|
||||
newCustomExchangeRate.UpdatedUnixTime = now
|
||||
newCustomExchangeRate.DeletedUnixTime = 0
|
||||
_, err = sess.Insert(newCustomExchangeRate)
|
||||
|
||||
return err
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return newCustomExchangeRate, defaultCurrencyExchangeRate, err
|
||||
}
|
||||
|
||||
// DeleteCustomExchangeRate deletes an existed user exchange rate data from database
|
||||
func (s *UserCustomExchangeRatesService) DeleteCustomExchangeRate(c core.Context, uid int64, currency string) error {
|
||||
if uid <= 0 {
|
||||
return errs.ErrUserIdInvalid
|
||||
}
|
||||
|
||||
now := time.Now().Unix()
|
||||
|
||||
updateModel := &models.UserCustomExchangeRate{
|
||||
DeletedUnixTime: now,
|
||||
}
|
||||
|
||||
return s.UserDataDB(uid).DoTransaction(c, func(sess *xorm.Session) error {
|
||||
deletedRows, err := sess.Cols("deleted_unix_time").Where("uid=? AND deleted_unix_time=? AND currency=?", uid, 0, currency).Update(updateModel)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
} else if deletedRows < 1 {
|
||||
return errs.ErrUserCustomExchangeRateNotFound
|
||||
}
|
||||
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
// DeleteAllCustomExchangeRates deletes all existed user exchange rate data from database
|
||||
func (s *UserCustomExchangeRatesService) DeleteAllCustomExchangeRates(c core.Context, uid int64) error {
|
||||
if uid <= 0 {
|
||||
return errs.ErrUserIdInvalid
|
||||
}
|
||||
|
||||
now := time.Now().Unix()
|
||||
|
||||
updateModel := &models.UserCustomExchangeRate{
|
||||
DeletedUnixTime: now,
|
||||
}
|
||||
|
||||
return s.UserDataDB(uid).DoTransaction(c, func(sess *xorm.Session) error {
|
||||
_, err := sess.Cols("deleted_unix_time").Where("uid=? AND deleted_unix_time=?", uid, 0).Update(updateModel)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
@@ -117,6 +117,7 @@ const (
|
||||
NationalBankOfUkraineDataSource string = "national_bank_of_ukraine"
|
||||
CentralBankOfUzbekistanDataSource string = "central_bank_of_uzbekistan"
|
||||
InternationalMonetaryFundDataSource string = "international_monetary_fund"
|
||||
UserCustomExchangeRatesDataSource string = "user_custom"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -914,7 +915,8 @@ func loadExchangeRatesConfiguration(config *Config, configFile *ini.File, sectio
|
||||
dataSource == SwissNationalBankDataSource ||
|
||||
dataSource == NationalBankOfUkraineDataSource ||
|
||||
dataSource == CentralBankOfUzbekistanDataSource ||
|
||||
dataSource == InternationalMonetaryFundDataSource {
|
||||
dataSource == InternationalMonetaryFundDataSource ||
|
||||
dataSource == UserCustomExchangeRatesDataSource {
|
||||
config.ExchangeRatesDataSource = dataSource
|
||||
} else {
|
||||
return errs.ErrInvalidExchangeRatesDataSource
|
||||
|
||||
Reference in New Issue
Block a user