diff --git a/cmd/webserver.go b/cmd/webserver.go index 38b1f6c5..973ee8d0 100644 --- a/cmd/webserver.go +++ b/cmd/webserver.go @@ -207,6 +207,7 @@ func startWebServer(c *cli.Context) error { apiV1Route.GET("/transactions/count.json", bindApi(api.Transactions.TransactionCountHandler)) apiV1Route.GET("/transactions/list.json", bindApi(api.Transactions.TransactionListHandler)) apiV1Route.GET("/transactions/list/by_month.json", bindApi(api.Transactions.TransactionMonthListHandler)) + apiV1Route.GET("/transactions/statistics.json", bindApi(api.Transactions.TransactionStatisticsHandler)) apiV1Route.GET("/transactions/get.json", bindApi(api.Transactions.TransactionGetHandler)) apiV1Route.POST("/transactions/add.json", bindApi(api.Transactions.TransactionCreateHandler)) apiV1Route.POST("/transactions/modify.json", bindApi(api.Transactions.TransactionModifyHandler)) @@ -231,9 +232,6 @@ func startWebServer(c *cli.Context) error { apiV1Route.POST("/transaction/tags/move.json", bindApi(api.TransactionTags.TagMoveHandler)) apiV1Route.POST("/transaction/tags/delete.json", bindApi(api.TransactionTags.TagDeleteHandler)) - // Statistics - apiV1Route.GET("/statistics/transaction.json", bindApi(api.Statistics.TransactionStatisticsHandler)) - // Exchange Rates apiV1Route.GET("/exchange_rates/latest.json", bindApi(api.ExchangeRates.LatestExchangeRateHandler)) } diff --git a/pkg/api/statistics.go b/pkg/api/statistics.go deleted file mode 100644 index 18849972..00000000 --- a/pkg/api/statistics.go +++ /dev/null @@ -1,53 +0,0 @@ -package api - -import ( - "github.com/mayswind/lab/pkg/core" - "github.com/mayswind/lab/pkg/errs" - "github.com/mayswind/lab/pkg/log" - "github.com/mayswind/lab/pkg/models" - "github.com/mayswind/lab/pkg/services" -) - -// StatisticApi represents statistic api -type StatisticApi struct { - transactions *services.TransactionService -} - -// Initialize an statistic api singleton instance -var ( - Statistics = &StatisticApi{ - transactions: services.Transactions, - } -) - -// TransactionStatisticsHandler returns transaction statistics of current user -func (a *StatisticApi) TransactionStatisticsHandler(c *core.Context) (interface{}, *errs.Error) { - var statisticReq models.TransactionStatisticRequest - err := c.ShouldBindQuery(&statisticReq) - - if err != nil { - log.WarnfWithRequestId(c, "[statistics.TransactionOverviewHandler] parse request failed, because %s", err.Error()) - return nil, errs.NewIncompleteOrIncorrectSubmissionError(err) - } - - uid := c.GetCurrentUid() - totalAmounts, err := a.transactions.GetAccountsAndCategoriesTotalIncomeAndExpense(uid, statisticReq.StartTime, statisticReq.EndTime) - - statisticResp := &models.TransactionStatisticResponse{ - StartTime: statisticReq.StartTime, - EndTime: statisticReq.EndTime, - } - - statisticResp.Items = make([]*models.TransactionStatisticResponseItem, len(totalAmounts)) - - for i := 0; i < len(totalAmounts); i++ { - totalAmountItem := totalAmounts[i] - statisticResp.Items[i] = &models.TransactionStatisticResponseItem{ - CategoryId: totalAmountItem.CategoryId, - AccountId: totalAmountItem.AccountId, - TotalAmount: totalAmountItem.Amount, - } - } - - return statisticResp, nil -} diff --git a/pkg/api/transactions.go b/pkg/api/transactions.go index 2cd2692e..ec0a2b1f 100644 --- a/pkg/api/transactions.go +++ b/pkg/api/transactions.go @@ -192,6 +192,38 @@ func (a *TransactionsApi) TransactionMonthListHandler(c *core.Context) (interfac return transactionResps, nil } +// TransactionStatisticsHandler returns transaction statistics of current user +func (a *TransactionsApi) TransactionStatisticsHandler(c *core.Context) (interface{}, *errs.Error) { + var statisticReq models.TransactionStatisticRequest + err := c.ShouldBindQuery(&statisticReq) + + if err != nil { + log.WarnfWithRequestId(c, "[transactions.TransactionOverviewHandler] parse request failed, because %s", err.Error()) + return nil, errs.NewIncompleteOrIncorrectSubmissionError(err) + } + + uid := c.GetCurrentUid() + totalAmounts, err := a.transactions.GetAccountsAndCategoriesTotalIncomeAndExpense(uid, statisticReq.StartTime, statisticReq.EndTime) + + statisticResp := &models.TransactionStatisticResponse{ + StartTime: statisticReq.StartTime, + EndTime: statisticReq.EndTime, + } + + statisticResp.Items = make([]*models.TransactionStatisticResponseItem, len(totalAmounts)) + + for i := 0; i < len(totalAmounts); i++ { + totalAmountItem := totalAmounts[i] + statisticResp.Items[i] = &models.TransactionStatisticResponseItem{ + CategoryId: totalAmountItem.CategoryId, + AccountId: totalAmountItem.AccountId, + TotalAmount: totalAmountItem.Amount, + } + } + + return statisticResp, nil +} + // TransactionGetHandler returns one specific transaction of current user func (a *TransactionsApi) TransactionGetHandler(c *core.Context) (interface{}, *errs.Error) { var transactionGetReq models.TransactionGetRequest diff --git a/pkg/models/statistic.go b/pkg/models/statistic.go deleted file mode 100644 index 421117ba..00000000 --- a/pkg/models/statistic.go +++ /dev/null @@ -1,21 +0,0 @@ -package models - -// TransactionStatisticRequest represents all parameters of transaction statistic request -type TransactionStatisticRequest struct { - StartTime int64 `form:"start_time" binding:"min=0"` - EndTime int64 `form:"end_time" binding:"min=0"` -} - -// TransactionStatisticResponse represents an item of transaction overview -type TransactionStatisticResponse struct { - StartTime int64 `json:"startTime"` - EndTime int64 `json:"endTime"` - Items []*TransactionStatisticResponseItem `json:"items"` -} - -// TransactionStatisticResponseItem represents total amount item for an response -type TransactionStatisticResponseItem struct { - CategoryId int64 `json:"categoryId,string"` - AccountId int64 `json:"accountId,string"` - TotalAmount int64 `json:"amount"` -} diff --git a/pkg/models/transaction.go b/pkg/models/transaction.go index ef443ae8..f0bfd1b9 100644 --- a/pkg/models/transaction.go +++ b/pkg/models/transaction.go @@ -119,6 +119,12 @@ type TransactionListInMonthByPageRequest struct { TrimTag bool `form:"trim_tag"` } +// TransactionStatisticRequest represents all parameters of transaction statistic request +type TransactionStatisticRequest struct { + StartTime int64 `form:"start_time" binding:"min=0"` + EndTime int64 `form:"end_time" binding:"min=0"` +} + // TransactionGetRequest represents all parameters of transaction getting request type TransactionGetRequest struct { Id int64 `form:"id,string" binding:"required,min=1"` @@ -170,6 +176,20 @@ type TransactionInfoPageWrapperResponse2 struct { TotalCount int64 `json:"total_count"` } +// TransactionStatisticResponse represents an item of transaction overview +type TransactionStatisticResponse struct { + StartTime int64 `json:"startTime"` + EndTime int64 `json:"endTime"` + Items []*TransactionStatisticResponseItem `json:"items"` +} + +// TransactionStatisticResponseItem represents total amount item for an response +type TransactionStatisticResponseItem struct { + CategoryId int64 `json:"categoryId,string"` + AccountId int64 `json:"accountId,string"` + TotalAmount int64 `json:"amount"` +} + // IsEditable returns whether this transaction can be edited func (t *Transaction) IsEditable(currentUser *User, utcOffset int16, account *Account, relatedAccount *Account) bool { if currentUser == nil || !currentUser.CanEditTransactionByTransactionTime(t.TransactionTime, utcOffset) { diff --git a/src/lib/services.js b/src/lib/services.js index 0720eeb3..b8312b3c 100644 --- a/src/lib/services.js +++ b/src/lib/services.js @@ -192,19 +192,6 @@ export default { return axios.get('v1/overviews/transaction.json' + (queryParams.length ? '?query=' + queryParams.join('|') : '')); }, - getTransactionStatistics: ({ startTime, endTime }) => { - const queryParams = []; - - if (startTime) { - queryParams.push(`start_time=${startTime}`); - } - - if (endTime) { - queryParams.push(`end_time=${endTime}`); - } - - return axios.get('v1/statistics/transaction.json' + (queryParams.length ? '?' + queryParams.join('&') : '')); - }, getAllAccounts: ({ visibleOnly }) => { return axios.get('v1/accounts/list.json?visible_only=' + !!visibleOnly); }, @@ -255,6 +242,19 @@ export default { getTransactions: ({ maxTime, minTime, type, categoryId, accountId, keyword }) => { return axios.get(`v1/transactions/list.json?max_time=${maxTime}&min_time=${minTime}&type=${type}&category_id=${categoryId}&account_id=${accountId}&keyword=${keyword}&count=50&trim_account=true&trim_category=true&trim_tag=true`); }, + getTransactionStatistics: ({ startTime, endTime }) => { + const queryParams = []; + + if (startTime) { + queryParams.push(`start_time=${startTime}`); + } + + if (endTime) { + queryParams.push(`end_time=${endTime}`); + } + + return axios.get('v1/transactions/statistics.json' + (queryParams.length ? '?' + queryParams.join('&') : '')); + }, getTransaction: ({ id }) => { return axios.get(`v1/transactions/get.json?id=${id}&trim_account=true&trim_category=true&trim_tag=true`); },