mirror of
https://github.com/mayswind/ezbookkeeping.git
synced 2026-05-17 00:12:11 +08:00
add transaction count api
This commit is contained in:
@@ -204,6 +204,7 @@ func startWebServer(c *cli.Context) error {
|
|||||||
apiV1Route.POST("/accounts/delete.json", bindApi(api.Accounts.AccountDeleteHandler))
|
apiV1Route.POST("/accounts/delete.json", bindApi(api.Accounts.AccountDeleteHandler))
|
||||||
|
|
||||||
// Transactions
|
// Transactions
|
||||||
|
apiV1Route.GET("/transactions/count.json", bindApi(api.Transactions.TransactionCountHandler))
|
||||||
apiV1Route.GET("/transactions/list.json", bindApi(api.Transactions.TransactionListHandler))
|
apiV1Route.GET("/transactions/list.json", bindApi(api.Transactions.TransactionListHandler))
|
||||||
apiV1Route.GET("/transactions/list/by_month.json", bindApi(api.Transactions.TransactionListHandler))
|
apiV1Route.GET("/transactions/list/by_month.json", bindApi(api.Transactions.TransactionListHandler))
|
||||||
apiV1Route.GET("/transactions/get.json", bindApi(api.Transactions.TransactionGetHandler))
|
apiV1Route.GET("/transactions/get.json", bindApi(api.Transactions.TransactionGetHandler))
|
||||||
|
|||||||
@@ -31,6 +31,46 @@ var (
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// TransactionCountHandler returns transaction total count of current user
|
||||||
|
func (a *TransactionsApi) TransactionCountHandler(c *core.Context) (interface{}, *errs.Error) {
|
||||||
|
var transactionCountReq models.TransactionCountRequest
|
||||||
|
err := c.ShouldBindQuery(&transactionCountReq)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.WarnfWithRequestId(c, "[transactions.TransactionCountHandler] parse request failed, because %s", err.Error())
|
||||||
|
return nil, errs.NewIncompleteOrIncorrectSubmissionError(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
uid := c.GetCurrentUid()
|
||||||
|
|
||||||
|
var allCategoryIds []int64
|
||||||
|
|
||||||
|
if transactionCountReq.CategoryId > 0 {
|
||||||
|
allSubCategories, err := a.transactionCategories.GetAllCategoriesByUid(uid, 0, transactionCountReq.CategoryId)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.WarnfWithRequestId(c, "[transactions.TransactionCountHandler] get transaction category error, because %s", err.Error())
|
||||||
|
return nil, errs.ErrOperationFailed
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(allSubCategories) > 0 {
|
||||||
|
for i := 0; i < len(allSubCategories); i++ {
|
||||||
|
allCategoryIds = append(allCategoryIds, allSubCategories[i].CategoryId)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
allCategoryIds = append(allCategoryIds, transactionCountReq.CategoryId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
totalCount, err := a.transactions.GetTransactionCount(uid, transactionCountReq.MaxTime, transactionCountReq.MinTime, transactionCountReq.Type, allCategoryIds, transactionCountReq.AccountId, transactionCountReq.Keyword)
|
||||||
|
|
||||||
|
countResp := &models.TransactionCountResponse{
|
||||||
|
Count: totalCount,
|
||||||
|
}
|
||||||
|
|
||||||
|
return countResp, nil
|
||||||
|
}
|
||||||
|
|
||||||
// TransactionListHandler returns transaction list of current user
|
// TransactionListHandler returns transaction list of current user
|
||||||
func (a *TransactionsApi) TransactionListHandler(c *core.Context) (interface{}, *errs.Error) {
|
func (a *TransactionsApi) TransactionListHandler(c *core.Context) (interface{}, *errs.Error) {
|
||||||
var transactionListReq models.TransactionListByMaxTimeRequest
|
var transactionListReq models.TransactionListByMaxTimeRequest
|
||||||
|
|||||||
@@ -80,6 +80,16 @@ type TransactionModifyRequest struct {
|
|||||||
Comment string `json:"comment" binding:"max=255"`
|
Comment string `json:"comment" binding:"max=255"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TransactionCountRequest represents transaction count request
|
||||||
|
type TransactionCountRequest struct {
|
||||||
|
Type TransactionDbType `form:"type" binding:"min=0,max=4"`
|
||||||
|
CategoryId int64 `form:"category_id" binding:"min=0"`
|
||||||
|
AccountId int64 `form:"account_id" binding:"min=0"`
|
||||||
|
Keyword string `form:"keyword"`
|
||||||
|
MaxTime int64 `form:"max_time" binding:"min=0"`
|
||||||
|
MinTime int64 `form:"min_time" binding:"min=0"`
|
||||||
|
}
|
||||||
|
|
||||||
// TransactionListByMaxTimeRequest represents all parameters of transaction listing by max time request
|
// TransactionListByMaxTimeRequest represents all parameters of transaction listing by max time request
|
||||||
type TransactionListByMaxTimeRequest struct {
|
type TransactionListByMaxTimeRequest struct {
|
||||||
Type TransactionDbType `form:"type" binding:"min=0,max=4"`
|
Type TransactionDbType `form:"type" binding:"min=0,max=4"`
|
||||||
@@ -143,6 +153,11 @@ type TransactionInfoResponse struct {
|
|||||||
Editable bool `json:"editable"`
|
Editable bool `json:"editable"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TransactionCountResponse represents transaction count response
|
||||||
|
type TransactionCountResponse struct {
|
||||||
|
Count int64 `json:"count"`
|
||||||
|
}
|
||||||
|
|
||||||
// TransactionInfoPageWrapperResponse represents a response of transaction which contains items and next id
|
// TransactionInfoPageWrapperResponse represents a response of transaction which contains items and next id
|
||||||
type TransactionInfoPageWrapperResponse struct {
|
type TransactionInfoPageWrapperResponse struct {
|
||||||
Items TransactionInfoResponseSlice `json:"items"`
|
Items TransactionInfoResponseSlice `json:"items"`
|
||||||
|
|||||||
+77
-119
@@ -75,68 +75,7 @@ func (s *TransactionService) GetTransactionsByMaxTime(uid int64, maxTransactionT
|
|||||||
var transactions []*models.Transaction
|
var transactions []*models.Transaction
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
condition := "uid=? AND deleted=?"
|
condition, conditionParams := s.getTransactionQueryCondition(uid, maxTransactionTime, minTransactionTime, transactionType, categoryIds, accountId, keyword, noDuplicated)
|
||||||
conditionParams := make([]interface{}, 0, 16)
|
|
||||||
conditionParams = append(conditionParams, uid)
|
|
||||||
conditionParams = append(conditionParams, false)
|
|
||||||
|
|
||||||
if models.TRANSACTION_DB_TYPE_MODIFY_BALANCE <= transactionType && transactionType <= models.TRANSACTION_DB_TYPE_EXPENSE {
|
|
||||||
condition = condition + " AND type=?"
|
|
||||||
conditionParams = append(conditionParams, transactionType)
|
|
||||||
} else if transactionType == models.TRANSACTION_DB_TYPE_TRANSFER_OUT || transactionType == models.TRANSACTION_DB_TYPE_TRANSFER_IN {
|
|
||||||
if accountId == 0 {
|
|
||||||
condition = condition + " AND type=?"
|
|
||||||
conditionParams = append(conditionParams, models.TRANSACTION_DB_TYPE_TRANSFER_OUT)
|
|
||||||
} else {
|
|
||||||
condition = condition + " AND (type=? OR type=?)"
|
|
||||||
conditionParams = append(conditionParams, models.TRANSACTION_DB_TYPE_TRANSFER_OUT)
|
|
||||||
conditionParams = append(conditionParams, models.TRANSACTION_DB_TYPE_TRANSFER_IN)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if noDuplicated && accountId == 0 {
|
|
||||||
condition = condition + " AND (type=? OR type=? OR type=? OR type=?)"
|
|
||||||
conditionParams = append(conditionParams, models.TRANSACTION_DB_TYPE_MODIFY_BALANCE)
|
|
||||||
conditionParams = append(conditionParams, models.TRANSACTION_DB_TYPE_INCOME)
|
|
||||||
conditionParams = append(conditionParams, models.TRANSACTION_DB_TYPE_EXPENSE)
|
|
||||||
conditionParams = append(conditionParams, models.TRANSACTION_DB_TYPE_TRANSFER_OUT)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(categoryIds) > 0 {
|
|
||||||
var conditions strings.Builder
|
|
||||||
|
|
||||||
for i := 0; i < len(categoryIds); i++ {
|
|
||||||
if i > 0 {
|
|
||||||
conditions.WriteString(",")
|
|
||||||
}
|
|
||||||
|
|
||||||
conditions.WriteString("?")
|
|
||||||
conditionParams = append(conditionParams, categoryIds[i])
|
|
||||||
}
|
|
||||||
|
|
||||||
condition = condition + " AND category_id IN (" + conditions.String() + ")"
|
|
||||||
}
|
|
||||||
|
|
||||||
if accountId > 0 {
|
|
||||||
condition = condition + " AND account_id=?"
|
|
||||||
conditionParams = append(conditionParams, accountId)
|
|
||||||
}
|
|
||||||
|
|
||||||
if keyword != "" {
|
|
||||||
condition = condition + " AND comment LIKE ?"
|
|
||||||
conditionParams = append(conditionParams, "%%"+keyword+"%%")
|
|
||||||
}
|
|
||||||
|
|
||||||
if maxTransactionTime > 0 {
|
|
||||||
condition = condition + " AND transaction_time<=?"
|
|
||||||
conditionParams = append(conditionParams, maxTransactionTime)
|
|
||||||
}
|
|
||||||
|
|
||||||
if minTransactionTime > 0 {
|
|
||||||
condition = condition + " AND transaction_time>=?"
|
|
||||||
conditionParams = append(conditionParams, minTransactionTime)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = s.UserDataDB(uid).Where(condition, conditionParams...).Limit(count, 0).OrderBy("transaction_time desc").Find(&transactions)
|
err = s.UserDataDB(uid).Where(condition, conditionParams...).Limit(count, 0).OrderBy("transaction_time desc").Find(&transactions)
|
||||||
|
|
||||||
return transactions, err
|
return transactions, err
|
||||||
@@ -164,65 +103,12 @@ func (s *TransactionService) GetTransactionsInMonthByPage(uid int64, year int, m
|
|||||||
|
|
||||||
endTime := startTime.AddDate(0, 1, 0)
|
endTime := startTime.AddDate(0, 1, 0)
|
||||||
|
|
||||||
startTransactionTime := utils.GetMinTransactionTimeFromUnixTime(startTime.Unix())
|
minTransactionTime := utils.GetMinTransactionTimeFromUnixTime(startTime.Unix())
|
||||||
endTransactionTime := utils.GetMinTransactionTimeFromUnixTime(endTime.Unix())
|
maxTransactionTime := utils.GetMinTransactionTimeFromUnixTime(endTime.Unix()) - 1
|
||||||
|
|
||||||
var transactions []*models.Transaction
|
var transactions []*models.Transaction
|
||||||
|
|
||||||
condition := "uid=? AND deleted=? AND transaction_time>=? AND transaction_time<?"
|
condition, conditionParams := s.getTransactionQueryCondition(uid, maxTransactionTime, minTransactionTime, transactionType, categoryIds, accountId, keyword, true)
|
||||||
conditionParams := make([]interface{}, 0, 16)
|
|
||||||
conditionParams = append(conditionParams, uid)
|
|
||||||
conditionParams = append(conditionParams, false)
|
|
||||||
conditionParams = append(conditionParams, startTransactionTime)
|
|
||||||
conditionParams = append(conditionParams, endTransactionTime)
|
|
||||||
|
|
||||||
if models.TRANSACTION_DB_TYPE_MODIFY_BALANCE <= transactionType && transactionType <= models.TRANSACTION_DB_TYPE_EXPENSE {
|
|
||||||
condition = condition + " AND type=?"
|
|
||||||
conditionParams = append(conditionParams, transactionType)
|
|
||||||
} else if transactionType == models.TRANSACTION_DB_TYPE_TRANSFER_OUT || transactionType == models.TRANSACTION_DB_TYPE_TRANSFER_IN {
|
|
||||||
if accountId == 0 {
|
|
||||||
condition = condition + " AND type=?"
|
|
||||||
conditionParams = append(conditionParams, models.TRANSACTION_DB_TYPE_TRANSFER_OUT)
|
|
||||||
} else {
|
|
||||||
condition = condition + " AND (type=? OR type=?)"
|
|
||||||
conditionParams = append(conditionParams, models.TRANSACTION_DB_TYPE_TRANSFER_OUT)
|
|
||||||
conditionParams = append(conditionParams, models.TRANSACTION_DB_TYPE_TRANSFER_IN)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if accountId == 0 {
|
|
||||||
condition = condition + " AND (type=? OR type=? OR type=? OR type=?)"
|
|
||||||
conditionParams = append(conditionParams, models.TRANSACTION_DB_TYPE_MODIFY_BALANCE)
|
|
||||||
conditionParams = append(conditionParams, models.TRANSACTION_DB_TYPE_INCOME)
|
|
||||||
conditionParams = append(conditionParams, models.TRANSACTION_DB_TYPE_EXPENSE)
|
|
||||||
conditionParams = append(conditionParams, models.TRANSACTION_DB_TYPE_TRANSFER_OUT)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(categoryIds) > 0 {
|
|
||||||
var conditions strings.Builder
|
|
||||||
|
|
||||||
for i := 0; i < len(categoryIds); i++ {
|
|
||||||
if i > 0 {
|
|
||||||
conditions.WriteString(",")
|
|
||||||
}
|
|
||||||
|
|
||||||
conditions.WriteString("?")
|
|
||||||
conditionParams = append(conditionParams, categoryIds[i])
|
|
||||||
}
|
|
||||||
|
|
||||||
condition = condition + " AND category_id IN (" + conditions.String() + ")"
|
|
||||||
}
|
|
||||||
|
|
||||||
if accountId > 0 {
|
|
||||||
condition = condition + " AND account_id=?"
|
|
||||||
conditionParams = append(conditionParams, accountId)
|
|
||||||
}
|
|
||||||
|
|
||||||
if keyword != "" {
|
|
||||||
condition = condition + " AND comment LIKE ?"
|
|
||||||
conditionParams = append(conditionParams, "%%"+keyword+"%%")
|
|
||||||
}
|
|
||||||
|
|
||||||
err = s.UserDataDB(uid).Where(condition, conditionParams...).Limit(count, count*(page-1)).OrderBy("transaction_time desc").Find(&transactions)
|
err = s.UserDataDB(uid).Where(condition, conditionParams...).Limit(count, count*(page-1)).OrderBy("transaction_time desc").Find(&transactions)
|
||||||
|
|
||||||
return transactions, err
|
return transactions, err
|
||||||
@@ -252,11 +138,17 @@ func (s *TransactionService) GetTransactionByTransactionId(uid int64, transactio
|
|||||||
|
|
||||||
// GetAllTransactionCount returns total count of transactions
|
// GetAllTransactionCount returns total count of transactions
|
||||||
func (s *TransactionService) GetAllTransactionCount(uid int64) (int64, error) {
|
func (s *TransactionService) GetAllTransactionCount(uid int64) (int64, error) {
|
||||||
|
return s.GetTransactionCount(uid, 0, 0, 0, nil, 0, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTransactionCount returns count of transactions
|
||||||
|
func (s *TransactionService) GetTransactionCount(uid int64, maxTransactionTime int64, minTransactionTime int64, transactionType models.TransactionDbType, categoryIds []int64, accountId int64, keyword string) (int64, error) {
|
||||||
if uid <= 0 {
|
if uid <= 0 {
|
||||||
return 0, errs.ErrUserIdInvalid
|
return 0, errs.ErrUserIdInvalid
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.UserDataDB(uid).Where("uid=? AND deleted=?", uid, false).Count(&models.Transaction{})
|
condition, conditionParams := s.getTransactionQueryCondition(uid, maxTransactionTime, minTransactionTime, transactionType, categoryIds, accountId, keyword, true)
|
||||||
|
return s.UserDataDB(uid).Where(condition, conditionParams...).Count(&models.Transaction{})
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMonthTransactionCount returns total count of transactions in given year and month
|
// GetMonthTransactionCount returns total count of transactions in given year and month
|
||||||
@@ -1122,6 +1014,72 @@ func (s *TransactionService) GetTransactionMapByList(transactions []*models.Tran
|
|||||||
return transactionMap
|
return transactionMap
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *TransactionService) getTransactionQueryCondition(uid int64, maxTransactionTime int64, minTransactionTime int64, transactionType models.TransactionDbType, categoryIds []int64, accountId int64, keyword string, noDuplicated bool) (string, []interface{}) {
|
||||||
|
condition := "uid=? AND deleted=?"
|
||||||
|
conditionParams := make([]interface{}, 0, 16)
|
||||||
|
conditionParams = append(conditionParams, uid)
|
||||||
|
conditionParams = append(conditionParams, false)
|
||||||
|
|
||||||
|
if maxTransactionTime > 0 {
|
||||||
|
condition = condition + " AND transaction_time<=?"
|
||||||
|
conditionParams = append(conditionParams, maxTransactionTime)
|
||||||
|
}
|
||||||
|
|
||||||
|
if minTransactionTime > 0 {
|
||||||
|
condition = condition + " AND transaction_time>=?"
|
||||||
|
conditionParams = append(conditionParams, minTransactionTime)
|
||||||
|
}
|
||||||
|
|
||||||
|
if models.TRANSACTION_DB_TYPE_MODIFY_BALANCE <= transactionType && transactionType <= models.TRANSACTION_DB_TYPE_EXPENSE {
|
||||||
|
condition = condition + " AND type=?"
|
||||||
|
conditionParams = append(conditionParams, transactionType)
|
||||||
|
} else if transactionType == models.TRANSACTION_DB_TYPE_TRANSFER_OUT || transactionType == models.TRANSACTION_DB_TYPE_TRANSFER_IN {
|
||||||
|
if accountId == 0 {
|
||||||
|
condition = condition + " AND type=?"
|
||||||
|
conditionParams = append(conditionParams, models.TRANSACTION_DB_TYPE_TRANSFER_OUT)
|
||||||
|
} else {
|
||||||
|
condition = condition + " AND (type=? OR type=?)"
|
||||||
|
conditionParams = append(conditionParams, models.TRANSACTION_DB_TYPE_TRANSFER_OUT)
|
||||||
|
conditionParams = append(conditionParams, models.TRANSACTION_DB_TYPE_TRANSFER_IN)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if noDuplicated && accountId == 0 {
|
||||||
|
condition = condition + " AND (type=? OR type=? OR type=? OR type=?)"
|
||||||
|
conditionParams = append(conditionParams, models.TRANSACTION_DB_TYPE_MODIFY_BALANCE)
|
||||||
|
conditionParams = append(conditionParams, models.TRANSACTION_DB_TYPE_INCOME)
|
||||||
|
conditionParams = append(conditionParams, models.TRANSACTION_DB_TYPE_EXPENSE)
|
||||||
|
conditionParams = append(conditionParams, models.TRANSACTION_DB_TYPE_TRANSFER_OUT)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(categoryIds) > 0 {
|
||||||
|
var conditions strings.Builder
|
||||||
|
|
||||||
|
for i := 0; i < len(categoryIds); i++ {
|
||||||
|
if i > 0 {
|
||||||
|
conditions.WriteString(",")
|
||||||
|
}
|
||||||
|
|
||||||
|
conditions.WriteString("?")
|
||||||
|
conditionParams = append(conditionParams, categoryIds[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
condition = condition + " AND category_id IN (" + conditions.String() + ")"
|
||||||
|
}
|
||||||
|
|
||||||
|
if accountId > 0 {
|
||||||
|
condition = condition + " AND account_id=?"
|
||||||
|
conditionParams = append(conditionParams, accountId)
|
||||||
|
}
|
||||||
|
|
||||||
|
if keyword != "" {
|
||||||
|
condition = condition + " AND comment LIKE ?"
|
||||||
|
conditionParams = append(conditionParams, "%%"+keyword+"%%")
|
||||||
|
}
|
||||||
|
|
||||||
|
return condition, conditionParams
|
||||||
|
}
|
||||||
|
|
||||||
func (s *TransactionService) isAccountIdValid(transaction *models.Transaction) error {
|
func (s *TransactionService) isAccountIdValid(transaction *models.Transaction) error {
|
||||||
if transaction.Type == models.TRANSACTION_DB_TYPE_MODIFY_BALANCE {
|
if transaction.Type == models.TRANSACTION_DB_TYPE_MODIFY_BALANCE {
|
||||||
if transaction.RelatedAccountId != 0 && transaction.RelatedAccountId != transaction.AccountId {
|
if transaction.RelatedAccountId != 0 && transaction.RelatedAccountId != transaction.AccountId {
|
||||||
|
|||||||
Reference in New Issue
Block a user