WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Commit 6430a52

Browse files
committed
tag filter supports selecting both included and excluded tags simultaneously
1 parent 45be96c commit 6430a52

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+1144
-699
lines changed

cmd/webserver.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ func startWebServer(c *core.CliContext) error {
116116
_ = v.RegisterValidation("validCurrency", validators.ValidCurrency)
117117
_ = v.RegisterValidation("validHexRGBColor", validators.ValidHexRGBColor)
118118
_ = v.RegisterValidation("validAmountFilter", validators.ValidAmountFilter)
119+
_ = v.RegisterValidation("validTagFilter", validators.ValidTagFilter)
119120
_ = v.RegisterValidation("validFiscalYearStart", validators.ValidateFiscalYearStart)
120121
}
121122

pkg/api/data_managements.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -372,14 +372,14 @@ func (a *DataManagementsApi) getExportedFileContent(c *core.WebContext, fileType
372372
return nil, "", errs.Or(err, errs.ErrOperationFailed)
373373
}
374374

375-
var allTagIds []int64
376-
noTags := exportTransactionDataReq.TagIds == "none"
375+
noTags := exportTransactionDataReq.TagFilter == models.TransactionNoTagFilterValue
376+
var tagFilters []*models.TransactionTagFilter
377377

378378
if !noTags {
379-
allTagIds, err = a.tags.GetTagIds(exportTransactionDataReq.TagIds)
379+
tagFilters, err = models.ParseTransactionTagFilter(exportTransactionDataReq.TagFilter)
380380

381381
if err != nil {
382-
log.Warnf(c, "[data_managements.getExportedFileContent] get transaction tag ids error, because %s", err.Error())
382+
log.Warnf(c, "[data_managements.getExportedFileContent] parse transaction tag filters error, because %s", err.Error())
383383
return nil, "", errs.Or(err, errs.ErrOperationFailed)
384384
}
385385
}
@@ -395,7 +395,7 @@ func (a *DataManagementsApi) getExportedFileContent(c *core.WebContext, fileType
395395
minTransactionTime = utils.GetMinTransactionTimeFromUnixTime(exportTransactionDataReq.MinTime)
396396
}
397397

398-
allTransactions, err := a.transactions.GetAllSpecifiedTransactions(c, uid, maxTransactionTime, minTransactionTime, exportTransactionDataReq.Type, allCategoryIds, allAccountIds, allTagIds, noTags, exportTransactionDataReq.TagFilterType, exportTransactionDataReq.AmountFilter, exportTransactionDataReq.Keyword, pageCountForDataExport, true)
398+
allTransactions, err := a.transactions.GetAllSpecifiedTransactions(c, uid, maxTransactionTime, minTransactionTime, exportTransactionDataReq.Type, allCategoryIds, allAccountIds, tagFilters, noTags, exportTransactionDataReq.AmountFilter, exportTransactionDataReq.Keyword, pageCountForDataExport, true)
399399

400400
if err != nil {
401401
log.Errorf(c, "[data_managements.getExportedFileContent] failed to all transactions user \"uid:%d\", because %s", uid, err.Error())

pkg/api/transactions.go

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -83,19 +83,19 @@ func (a *TransactionsApi) TransactionCountHandler(c *core.WebContext) (any, *err
8383
return nil, errs.Or(err, errs.ErrOperationFailed)
8484
}
8585

86-
var allTagIds []int64
87-
noTags := transactionCountReq.TagIds == "none"
86+
noTags := transactionCountReq.TagFilter == models.TransactionNoTagFilterValue
87+
var tagFilters []*models.TransactionTagFilter
8888

8989
if !noTags {
90-
allTagIds, err = a.transactionTags.GetTagIds(transactionCountReq.TagIds)
90+
tagFilters, err = models.ParseTransactionTagFilter(transactionCountReq.TagFilter)
9191

9292
if err != nil {
93-
log.Warnf(c, "[transactions.TransactionCountHandler] get transaction tag ids error, because %s", err.Error())
93+
log.Warnf(c, "[transactions.TransactionCountHandler] parse transaction filters error, because %s", err.Error())
9494
return nil, errs.Or(err, errs.ErrOperationFailed)
9595
}
9696
}
9797

98-
totalCount, err := a.transactions.GetTransactionCount(c, uid, transactionCountReq.MaxTime, transactionCountReq.MinTime, transactionCountReq.Type, allCategoryIds, allAccountIds, allTagIds, noTags, transactionCountReq.TagFilterType, transactionCountReq.AmountFilter, transactionCountReq.Keyword)
98+
totalCount, err := a.transactions.GetTransactionCount(c, uid, transactionCountReq.MaxTime, transactionCountReq.MinTime, transactionCountReq.Type, allCategoryIds, allAccountIds, tagFilters, noTags, transactionCountReq.AmountFilter, transactionCountReq.Keyword)
9999

100100
if err != nil {
101101
log.Errorf(c, "[transactions.TransactionCountHandler] failed to get transaction count for user \"uid:%d\", because %s", uid, err.Error())
@@ -151,30 +151,30 @@ func (a *TransactionsApi) TransactionListHandler(c *core.WebContext) (any, *errs
151151
return nil, errs.Or(err, errs.ErrOperationFailed)
152152
}
153153

154-
var allTagIds []int64
155-
noTags := transactionListReq.TagIds == "none"
154+
noTags := transactionListReq.TagFilter == models.TransactionNoTagFilterValue
155+
var tagFilters []*models.TransactionTagFilter
156156

157157
if !noTags {
158-
allTagIds, err = a.transactionTags.GetTagIds(transactionListReq.TagIds)
158+
tagFilters, err = models.ParseTransactionTagFilter(transactionListReq.TagFilter)
159159

160160
if err != nil {
161-
log.Warnf(c, "[transactions.TransactionListHandler] get transaction tag ids error, because %s", err.Error())
161+
log.Warnf(c, "[transactions.TransactionListHandler] parse transaction tag filters error, because %s", err.Error())
162162
return nil, errs.Or(err, errs.ErrOperationFailed)
163163
}
164164
}
165165

166166
var totalCount int64
167167

168168
if transactionListReq.WithCount {
169-
totalCount, err = a.transactions.GetTransactionCount(c, uid, transactionListReq.MaxTime, transactionListReq.MinTime, transactionListReq.Type, allCategoryIds, allAccountIds, allTagIds, noTags, transactionListReq.TagFilterType, transactionListReq.AmountFilter, transactionListReq.Keyword)
169+
totalCount, err = a.transactions.GetTransactionCount(c, uid, transactionListReq.MaxTime, transactionListReq.MinTime, transactionListReq.Type, allCategoryIds, allAccountIds, tagFilters, noTags, transactionListReq.AmountFilter, transactionListReq.Keyword)
170170

171171
if err != nil {
172172
log.Errorf(c, "[transactions.TransactionListHandler] failed to get transaction count for user \"uid:%d\", because %s", uid, err.Error())
173173
return nil, errs.Or(err, errs.ErrOperationFailed)
174174
}
175175
}
176176

177-
transactions, err := a.transactions.GetTransactionsByMaxTime(c, uid, transactionListReq.MaxTime, transactionListReq.MinTime, transactionListReq.Type, allCategoryIds, allAccountIds, allTagIds, noTags, transactionListReq.TagFilterType, transactionListReq.AmountFilter, transactionListReq.Keyword, transactionListReq.Page, transactionListReq.Count, true, true)
177+
transactions, err := a.transactions.GetTransactionsByMaxTime(c, uid, transactionListReq.MaxTime, transactionListReq.MinTime, transactionListReq.Type, allCategoryIds, allAccountIds, tagFilters, noTags, transactionListReq.AmountFilter, transactionListReq.Keyword, transactionListReq.Page, transactionListReq.Count, true, true)
178178

179179
if err != nil {
180180
log.Errorf(c, "[transactions.TransactionListHandler] failed to get transactions earlier than \"%d\" for user \"uid:%d\", because %s", transactionListReq.MaxTime, uid, err.Error())
@@ -254,19 +254,19 @@ func (a *TransactionsApi) TransactionMonthListHandler(c *core.WebContext) (any,
254254
return nil, errs.Or(err, errs.ErrOperationFailed)
255255
}
256256

257-
var allTagIds []int64
258-
noTags := transactionListReq.TagIds == "none"
257+
noTags := transactionListReq.TagFilter == models.TransactionNoTagFilterValue
258+
var tagFilters []*models.TransactionTagFilter
259259

260260
if !noTags {
261-
allTagIds, err = a.transactionTags.GetTagIds(transactionListReq.TagIds)
261+
tagFilters, err = models.ParseTransactionTagFilter(transactionListReq.TagFilter)
262262

263263
if err != nil {
264-
log.Warnf(c, "[transactions.TransactionMonthListHandler] get transaction tag ids error, because %s", err.Error())
264+
log.Warnf(c, "[transactions.TransactionMonthListHandler] parse transaction tag filters error, because %s", err.Error())
265265
return nil, errs.Or(err, errs.ErrOperationFailed)
266266
}
267267
}
268268

269-
transactions, err := a.transactions.GetTransactionsInMonthByPage(c, uid, transactionListReq.Year, transactionListReq.Month, transactionListReq.Type, allCategoryIds, allAccountIds, allTagIds, noTags, transactionListReq.TagFilterType, transactionListReq.AmountFilter, transactionListReq.Keyword)
269+
transactions, err := a.transactions.GetTransactionsInMonthByPage(c, uid, transactionListReq.Year, transactionListReq.Month, transactionListReq.Type, allCategoryIds, allAccountIds, tagFilters, noTags, transactionListReq.AmountFilter, transactionListReq.Keyword)
270270

271271
if err != nil {
272272
log.Errorf(c, "[transactions.TransactionMonthListHandler] failed to get transactions in month \"%d-%d\" for user \"uid:%d\", because %s", transactionListReq.Year, transactionListReq.Month, uid, err.Error())
@@ -413,20 +413,20 @@ func (a *TransactionsApi) TransactionStatisticsHandler(c *core.WebContext) (any,
413413
return nil, errs.ErrClientTimezoneOffsetInvalid
414414
}
415415

416-
var allTagIds []int64
417-
noTags := statisticReq.TagIds == "none"
416+
noTags := statisticReq.TagFilter == models.TransactionNoTagFilterValue
417+
var tagFilters []*models.TransactionTagFilter
418418

419419
if !noTags {
420-
allTagIds, err = a.transactionTags.GetTagIds(statisticReq.TagIds)
420+
tagFilters, err = models.ParseTransactionTagFilter(statisticReq.TagFilter)
421421

422422
if err != nil {
423-
log.Warnf(c, "[transactions.TransactionStatisticsHandler] get transaction tag ids error, because %s", err.Error())
423+
log.Warnf(c, "[transactions.TransactionStatisticsHandler] parse transaction tag filters error, because %s", err.Error())
424424
return nil, errs.Or(err, errs.ErrOperationFailed)
425425
}
426426
}
427427

428428
uid := c.GetCurrentUid()
429-
totalAmounts, err := a.transactions.GetAccountsAndCategoriesTotalInflowAndOutflow(c, uid, statisticReq.StartTime, statisticReq.EndTime, allTagIds, noTags, statisticReq.TagFilterType, statisticReq.Keyword, utcOffset, statisticReq.UseTransactionTimezone)
429+
totalAmounts, err := a.transactions.GetAccountsAndCategoriesTotalInflowAndOutflow(c, uid, statisticReq.StartTime, statisticReq.EndTime, tagFilters, noTags, statisticReq.Keyword, utcOffset, statisticReq.UseTransactionTimezone)
430430

431431
if err != nil {
432432
log.Errorf(c, "[transactions.TransactionStatisticsHandler] failed to get accounts and categories total income and expense for user \"uid:%d\", because %s", uid, err.Error())
@@ -481,20 +481,20 @@ func (a *TransactionsApi) TransactionStatisticsTrendsHandler(c *core.WebContext)
481481
return nil, errs.Or(err, errs.ErrOperationFailed)
482482
}
483483

484-
var allTagIds []int64
485-
noTags := statisticTrendsReq.TagIds == "none"
484+
noTags := statisticTrendsReq.TagFilter == models.TransactionNoTagFilterValue
485+
var tagFilters []*models.TransactionTagFilter
486486

487487
if !noTags {
488-
allTagIds, err = a.transactionTags.GetTagIds(statisticTrendsReq.TagIds)
488+
tagFilters, err = models.ParseTransactionTagFilter(statisticTrendsReq.TagFilter)
489489

490490
if err != nil {
491-
log.Warnf(c, "[transactions.TransactionStatisticsTrendsHandler] get transaction tag ids error, because %s", err.Error())
491+
log.Warnf(c, "[transactions.TransactionStatisticsTrendsHandler] parse transaction tag filters error, because %s", err.Error())
492492
return nil, errs.Or(err, errs.ErrOperationFailed)
493493
}
494494
}
495495

496496
uid := c.GetCurrentUid()
497-
allMonthlyTotalAmounts, err := a.transactions.GetAccountsAndCategoriesMonthlyInflowAndOutflow(c, uid, startYear, startMonth, endYear, endMonth, allTagIds, noTags, statisticTrendsReq.TagFilterType, statisticTrendsReq.Keyword, utcOffset, statisticTrendsReq.UseTransactionTimezone)
497+
allMonthlyTotalAmounts, err := a.transactions.GetAccountsAndCategoriesMonthlyInflowAndOutflow(c, uid, startYear, startMonth, endYear, endMonth, tagFilters, noTags, statisticTrendsReq.Keyword, utcOffset, statisticTrendsReq.UseTransactionTimezone)
498498

499499
if err != nil {
500500
log.Errorf(c, "[transactions.TransactionStatisticsTrendsHandler] failed to get accounts and categories total income and expense for user \"uid:%d\", because %s", uid, err.Error())

pkg/errs/global.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,3 +94,8 @@ func GetParameterInvalidHexRGBColorMessage(field string) string {
9494
func GetParameterInvalidAmountFilterMessage(field string) string {
9595
return fmt.Sprintf("parameter \"%s\" is invalid amount filter", field)
9696
}
97+
98+
// GetParameterInvalidTagFilterMessage returns specific error message for invalid tag filter parameter error
99+
func GetParameterInvalidTagFilterMessage(field string) string {
100+
return fmt.Sprintf("parameter \"%s\" is invalid tag filter", field)
101+
}

pkg/mcp/query_transactions_tool_handler.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,14 +153,14 @@ func (h *mcpQueryTransactionsToolHandler) Handle(c *core.WebContext, callToolReq
153153
}
154154
}
155155

156-
totalCount, err := services.GetTransactionService().GetTransactionCount(c, uid, maxTransactionTime, minTransactionTime, transactionType, filterCategoryIds, filterAccountIds, nil, false, models.TRANSACTION_TAG_FILTER_HAS_ANY, "", queryTransactionsRequest.Keyword)
156+
totalCount, err := services.GetTransactionService().GetTransactionCount(c, uid, maxTransactionTime, minTransactionTime, transactionType, filterCategoryIds, filterAccountIds, nil, false, "", queryTransactionsRequest.Keyword)
157157

158158
if err != nil {
159159
log.Errorf(c, "[transactions.TransactionListHandler] failed to get transaction count for user \"uid:%d\", because %s", uid, err.Error())
160160
return nil, nil, err
161161
}
162162

163-
transactions, err := services.GetTransactionService().GetTransactionsByMaxTime(c, uid, maxTransactionTime, minTransactionTime, transactionType, filterCategoryIds, filterAccountIds, nil, false, models.TRANSACTION_TAG_FILTER_HAS_ANY, "", queryTransactionsRequest.Keyword, queryTransactionsRequest.Page, queryTransactionsRequest.Count, false, true)
163+
transactions, err := services.GetTransactionService().GetTransactionsByMaxTime(c, uid, maxTransactionTime, minTransactionTime, transactionType, filterCategoryIds, filterAccountIds, nil, false, "", queryTransactionsRequest.Keyword, queryTransactionsRequest.Page, queryTransactionsRequest.Count, false, true)
164164
structuredResponse, response, err := h.createNewMCPQueryTransactionsResponse(c, &queryTransactionsRequest, transactions, totalCount, services.GetAccountService().GetAccountMapByList(allAccounts), services.GetTransactionCategoryService().GetCategoryMapByList(allCategories))
165165

166166
if err != nil {

pkg/models/data_management.go

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,12 @@ type DataStatisticsResponse struct {
2424

2525
// ExportTransactionDataRequest represents export transaction request
2626
type ExportTransactionDataRequest struct {
27-
Type TransactionType `form:"type" binding:"min=0,max=4"`
28-
CategoryIds string `form:"category_ids"`
29-
AccountIds string `form:"account_ids"`
30-
TagIds string `form:"tag_ids"`
31-
TagFilterType TransactionTagFilterType `form:"tag_filter_type" binding:"min=0,max=3"`
32-
AmountFilter string `form:"amount_filter" binding:"validAmountFilter"`
33-
Keyword string `form:"keyword"`
34-
MaxTime int64 `form:"max_time" binding:"min=0"` // Unix timestamp in seconds
35-
MinTime int64 `form:"min_time" binding:"min=0"` // Unix timestamp in seconds
27+
Type TransactionType `form:"type" binding:"min=0,max=4"`
28+
CategoryIds string `form:"category_ids"`
29+
AccountIds string `form:"account_ids"`
30+
TagFilter string `form:"tag_filter" binding:"validTagFilter"`
31+
AmountFilter string `form:"amount_filter" binding:"validAmountFilter"`
32+
Keyword string `form:"keyword"`
33+
MaxTime int64 `form:"max_time" binding:"min=0"` // Unix timestamp in seconds
34+
MinTime int64 `form:"min_time" binding:"min=0"` // Unix timestamp in seconds
3635
}

0 commit comments

Comments
 (0)