mirror of
https://github.com/mayswind/ezbookkeeping.git
synced 2026-05-22 02:34:26 +08:00
support transaction tag filter type
This commit is contained in:
@@ -89,7 +89,7 @@ func (a *TransactionsApi) TransactionCountHandler(c *core.WebContext) (any, *err
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
totalCount, err := a.transactions.GetTransactionCount(c, uid, transactionCountReq.MaxTime, transactionCountReq.MinTime, transactionCountReq.Type, allCategoryIds, allAccountIds, allTagIds, noTags, transactionCountReq.AmountFilter, transactionCountReq.Keyword)
|
totalCount, err := a.transactions.GetTransactionCount(c, uid, transactionCountReq.MaxTime, transactionCountReq.MinTime, transactionCountReq.Type, allCategoryIds, allAccountIds, allTagIds, noTags, transactionCountReq.TagFilterType, transactionCountReq.AmountFilter, transactionCountReq.Keyword)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf(c, "[transactions.TransactionCountHandler] failed to get transaction count for user \"uid:%d\", because %s", uid, err.Error())
|
log.Errorf(c, "[transactions.TransactionCountHandler] failed to get transaction count for user \"uid:%d\", because %s", uid, err.Error())
|
||||||
@@ -160,7 +160,7 @@ func (a *TransactionsApi) TransactionListHandler(c *core.WebContext) (any, *errs
|
|||||||
var totalCount int64
|
var totalCount int64
|
||||||
|
|
||||||
if transactionListReq.WithCount {
|
if transactionListReq.WithCount {
|
||||||
totalCount, err = a.transactions.GetTransactionCount(c, uid, transactionListReq.MaxTime, transactionListReq.MinTime, transactionListReq.Type, allCategoryIds, allAccountIds, allTagIds, noTags, transactionListReq.AmountFilter, transactionListReq.Keyword)
|
totalCount, err = a.transactions.GetTransactionCount(c, uid, transactionListReq.MaxTime, transactionListReq.MinTime, transactionListReq.Type, allCategoryIds, allAccountIds, allTagIds, noTags, transactionListReq.TagFilterType, transactionListReq.AmountFilter, transactionListReq.Keyword)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf(c, "[transactions.TransactionListHandler] failed to get transaction count for user \"uid:%d\", because %s", uid, err.Error())
|
log.Errorf(c, "[transactions.TransactionListHandler] failed to get transaction count for user \"uid:%d\", because %s", uid, err.Error())
|
||||||
@@ -168,7 +168,7 @@ func (a *TransactionsApi) TransactionListHandler(c *core.WebContext) (any, *errs
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
transactions, err := a.transactions.GetTransactionsByMaxTime(c, uid, transactionListReq.MaxTime, transactionListReq.MinTime, transactionListReq.Type, allCategoryIds, allAccountIds, allTagIds, noTags, transactionListReq.AmountFilter, transactionListReq.Keyword, transactionListReq.Page, transactionListReq.Count, true, true)
|
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)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf(c, "[transactions.TransactionListHandler] failed to get transactions earlier than \"%d\" for user \"uid:%d\", because %s", transactionListReq.MaxTime, uid, err.Error())
|
log.Errorf(c, "[transactions.TransactionListHandler] failed to get transactions earlier than \"%d\" for user \"uid:%d\", because %s", transactionListReq.MaxTime, uid, err.Error())
|
||||||
@@ -260,7 +260,7 @@ func (a *TransactionsApi) TransactionMonthListHandler(c *core.WebContext) (any,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
transactions, err := a.transactions.GetTransactionsInMonthByPage(c, uid, transactionListReq.Year, transactionListReq.Month, transactionListReq.Type, allCategoryIds, allAccountIds, allTagIds, noTags, transactionListReq.AmountFilter, transactionListReq.Keyword)
|
transactions, err := a.transactions.GetTransactionsInMonthByPage(c, uid, transactionListReq.Year, transactionListReq.Month, transactionListReq.Type, allCategoryIds, allAccountIds, allTagIds, noTags, transactionListReq.TagFilterType, transactionListReq.AmountFilter, transactionListReq.Keyword)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
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())
|
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())
|
||||||
|
|||||||
+49
-35
@@ -66,6 +66,17 @@ func (s TransactionDbType) ToTransactionType() (TransactionType, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TransactionTagFilterType represents transaction tag filter type
|
||||||
|
type TransactionTagFilterType byte
|
||||||
|
|
||||||
|
// Transaction tag filter types
|
||||||
|
const (
|
||||||
|
TRANSACTION_TAG_FILTER_HAS_ANY TransactionTagFilterType = 0
|
||||||
|
TRANSACTION_TAG_FILTER_HAS_ALL TransactionTagFilterType = 1
|
||||||
|
TRANSACTION_TAG_FILTER_NOT_HAS_ANY TransactionTagFilterType = 2
|
||||||
|
TRANSACTION_TAG_FILTER_NOT_HAS_ALL TransactionTagFilterType = 3
|
||||||
|
)
|
||||||
|
|
||||||
// Transaction represents transaction data stored in database
|
// Transaction represents transaction data stored in database
|
||||||
type Transaction struct {
|
type Transaction struct {
|
||||||
TransactionId int64 `xorm:"PK"`
|
TransactionId int64 `xorm:"PK"`
|
||||||
@@ -140,49 +151,52 @@ type TransactionImportRequest struct {
|
|||||||
|
|
||||||
// TransactionCountRequest represents transaction count request
|
// TransactionCountRequest represents transaction count request
|
||||||
type TransactionCountRequest struct {
|
type TransactionCountRequest struct {
|
||||||
Type TransactionDbType `form:"type" binding:"min=0,max=4"`
|
Type TransactionDbType `form:"type" binding:"min=0,max=4"`
|
||||||
CategoryIds string `form:"category_ids"`
|
CategoryIds string `form:"category_ids"`
|
||||||
AccountIds string `form:"account_ids"`
|
AccountIds string `form:"account_ids"`
|
||||||
TagIds string `form:"tag_ids"`
|
TagIds string `form:"tag_ids"`
|
||||||
AmountFilter string `form:"amount_filter" binding:"validAmountFilter"`
|
TagFilterType TransactionTagFilterType `form:"tag_filter_type" binding:"min=0,max=3"`
|
||||||
Keyword string `form:"keyword"`
|
AmountFilter string `form:"amount_filter" binding:"validAmountFilter"`
|
||||||
MaxTime int64 `form:"max_time" binding:"min=0"`
|
Keyword string `form:"keyword"`
|
||||||
MinTime int64 `form:"min_time" binding:"min=0"`
|
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"`
|
||||||
CategoryIds string `form:"category_ids"`
|
CategoryIds string `form:"category_ids"`
|
||||||
AccountIds string `form:"account_ids"`
|
AccountIds string `form:"account_ids"`
|
||||||
TagIds string `form:"tag_ids"`
|
TagIds string `form:"tag_ids"`
|
||||||
AmountFilter string `form:"amount_filter" binding:"validAmountFilter"`
|
TagFilterType TransactionTagFilterType `form:"tag_filter_type" binding:"min=0,max=3"`
|
||||||
Keyword string `form:"keyword"`
|
AmountFilter string `form:"amount_filter" binding:"validAmountFilter"`
|
||||||
MaxTime int64 `form:"max_time" binding:"min=0"`
|
Keyword string `form:"keyword"`
|
||||||
MinTime int64 `form:"min_time" binding:"min=0"`
|
MaxTime int64 `form:"max_time" binding:"min=0"`
|
||||||
Page int32 `form:"page" binding:"min=0"`
|
MinTime int64 `form:"min_time" binding:"min=0"`
|
||||||
Count int32 `form:"count" binding:"required,min=1,max=50"`
|
Page int32 `form:"page" binding:"min=0"`
|
||||||
WithCount bool `form:"with_count"`
|
Count int32 `form:"count" binding:"required,min=1,max=50"`
|
||||||
WithPictures bool `form:"with_pictures"`
|
WithCount bool `form:"with_count"`
|
||||||
TrimAccount bool `form:"trim_account"`
|
WithPictures bool `form:"with_pictures"`
|
||||||
TrimCategory bool `form:"trim_category"`
|
TrimAccount bool `form:"trim_account"`
|
||||||
TrimTag bool `form:"trim_tag"`
|
TrimCategory bool `form:"trim_category"`
|
||||||
|
TrimTag bool `form:"trim_tag"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// TransactionListInMonthByPageRequest represents all parameters of transaction listing by month request
|
// TransactionListInMonthByPageRequest represents all parameters of transaction listing by month request
|
||||||
type TransactionListInMonthByPageRequest struct {
|
type TransactionListInMonthByPageRequest struct {
|
||||||
Year int32 `form:"year" binding:"required,min=1"`
|
Year int32 `form:"year" binding:"required,min=1"`
|
||||||
Month int32 `form:"month" binding:"required,min=1"`
|
Month int32 `form:"month" binding:"required,min=1"`
|
||||||
Type TransactionDbType `form:"type" binding:"min=0,max=4"`
|
Type TransactionDbType `form:"type" binding:"min=0,max=4"`
|
||||||
CategoryIds string `form:"category_ids"`
|
CategoryIds string `form:"category_ids"`
|
||||||
AccountIds string `form:"account_ids"`
|
AccountIds string `form:"account_ids"`
|
||||||
TagIds string `form:"tag_ids"`
|
TagIds string `form:"tag_ids"`
|
||||||
AmountFilter string `form:"amount_filter" binding:"validAmountFilter"`
|
TagFilterType TransactionTagFilterType `form:"tag_filter_type" binding:"min=0,max=3"`
|
||||||
Keyword string `form:"keyword"`
|
AmountFilter string `form:"amount_filter" binding:"validAmountFilter"`
|
||||||
WithPictures bool `form:"with_pictures"`
|
Keyword string `form:"keyword"`
|
||||||
TrimAccount bool `form:"trim_account"`
|
WithPictures bool `form:"with_pictures"`
|
||||||
TrimCategory bool `form:"trim_category"`
|
TrimAccount bool `form:"trim_account"`
|
||||||
TrimTag bool `form:"trim_tag"`
|
TrimCategory bool `form:"trim_category"`
|
||||||
|
TrimTag bool `form:"trim_tag"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// TransactionStatisticRequest represents all parameters of transaction statistic request
|
// TransactionStatisticRequest represents all parameters of transaction statistic request
|
||||||
|
|||||||
@@ -75,11 +75,11 @@ func (s *TransactionService) GetAllTransactions(c core.Context, uid int64, pageC
|
|||||||
|
|
||||||
// GetAllTransactionsByMaxTime returns all transactions before given time
|
// GetAllTransactionsByMaxTime returns all transactions before given time
|
||||||
func (s *TransactionService) GetAllTransactionsByMaxTime(c core.Context, uid int64, maxTransactionTime int64, count int32, noDuplicated bool) ([]*models.Transaction, error) {
|
func (s *TransactionService) GetAllTransactionsByMaxTime(c core.Context, uid int64, maxTransactionTime int64, count int32, noDuplicated bool) ([]*models.Transaction, error) {
|
||||||
return s.GetTransactionsByMaxTime(c, uid, maxTransactionTime, 0, 0, nil, nil, nil, false, "", "", 1, count, false, noDuplicated)
|
return s.GetTransactionsByMaxTime(c, uid, maxTransactionTime, 0, 0, nil, nil, nil, false, models.TRANSACTION_TAG_FILTER_HAS_ANY, "", "", 1, count, false, noDuplicated)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTransactionsByMaxTime returns transactions before given time
|
// GetTransactionsByMaxTime returns transactions before given time
|
||||||
func (s *TransactionService) GetTransactionsByMaxTime(c core.Context, uid int64, maxTransactionTime int64, minTransactionTime int64, transactionType models.TransactionDbType, categoryIds []int64, accountIds []int64, tagIds []int64, noTags bool, amountFilter string, keyword string, page int32, count int32, needOneMoreItem bool, noDuplicated bool) ([]*models.Transaction, error) {
|
func (s *TransactionService) GetTransactionsByMaxTime(c core.Context, uid int64, maxTransactionTime int64, minTransactionTime int64, transactionType models.TransactionDbType, categoryIds []int64, accountIds []int64, tagIds []int64, noTags bool, tagFilterType models.TransactionTagFilterType, amountFilter string, keyword string, page int32, count int32, needOneMoreItem bool, noDuplicated bool) ([]*models.Transaction, error) {
|
||||||
if uid <= 0 {
|
if uid <= 0 {
|
||||||
return nil, errs.ErrUserIdInvalid
|
return nil, errs.ErrUserIdInvalid
|
||||||
}
|
}
|
||||||
@@ -103,14 +103,9 @@ func (s *TransactionService) GetTransactionsByMaxTime(c core.Context, uid int64,
|
|||||||
actualCount++
|
actualCount++
|
||||||
}
|
}
|
||||||
|
|
||||||
condition, conditionParams := s.getTransactionQueryCondition(uid, maxTransactionTime, minTransactionTime, transactionType, categoryIds, accountIds, tagIds, amountFilter, keyword, noDuplicated)
|
condition, conditionParams := s.buildTransactionQueryCondition(uid, maxTransactionTime, minTransactionTime, transactionType, categoryIds, accountIds, tagIds, amountFilter, keyword, noDuplicated)
|
||||||
sess := s.UserDataDB(uid).NewSession(c).Where(condition, conditionParams...)
|
sess := s.UserDataDB(uid).NewSession(c).Where(condition, conditionParams...)
|
||||||
|
sess = s.appendFilterTagIdsConditionToQuery(sess, uid, maxTransactionTime, minTransactionTime, tagIds, noTags, tagFilterType)
|
||||||
if len(tagIds) > 0 {
|
|
||||||
sess.In("transaction_id", s.getTransactionQueryByTagIdsCondition(uid, maxTransactionTime, minTransactionTime, tagIds))
|
|
||||||
} else if noTags {
|
|
||||||
sess.NotIn("transaction_id", s.getTransactionQueryByAllTagIdsCondition(uid, maxTransactionTime, minTransactionTime))
|
|
||||||
}
|
|
||||||
|
|
||||||
err = sess.Limit(int(actualCount), int(count*(page-1))).OrderBy("transaction_time desc").Find(&transactions)
|
err = sess.Limit(int(actualCount), int(count*(page-1))).OrderBy("transaction_time desc").Find(&transactions)
|
||||||
|
|
||||||
@@ -118,7 +113,7 @@ func (s *TransactionService) GetTransactionsByMaxTime(c core.Context, uid int64,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetTransactionsInMonthByPage returns all transactions in given year and month
|
// GetTransactionsInMonthByPage returns all transactions in given year and month
|
||||||
func (s *TransactionService) GetTransactionsInMonthByPage(c core.Context, uid int64, year int32, month int32, transactionType models.TransactionDbType, categoryIds []int64, accountIds []int64, tagIds []int64, noTags bool, amountFilter string, keyword string) ([]*models.Transaction, error) {
|
func (s *TransactionService) GetTransactionsInMonthByPage(c core.Context, uid int64, year int32, month int32, transactionType models.TransactionDbType, categoryIds []int64, accountIds []int64, tagIds []int64, noTags bool, tagFilterType models.TransactionTagFilterType, amountFilter string, keyword string) ([]*models.Transaction, error) {
|
||||||
if uid <= 0 {
|
if uid <= 0 {
|
||||||
return nil, errs.ErrUserIdInvalid
|
return nil, errs.ErrUserIdInvalid
|
||||||
}
|
}
|
||||||
@@ -131,14 +126,9 @@ func (s *TransactionService) GetTransactionsInMonthByPage(c core.Context, uid in
|
|||||||
|
|
||||||
var transactions []*models.Transaction
|
var transactions []*models.Transaction
|
||||||
|
|
||||||
condition, conditionParams := s.getTransactionQueryCondition(uid, maxTransactionTime, minTransactionTime, transactionType, categoryIds, accountIds, tagIds, amountFilter, keyword, true)
|
condition, conditionParams := s.buildTransactionQueryCondition(uid, maxTransactionTime, minTransactionTime, transactionType, categoryIds, accountIds, tagIds, amountFilter, keyword, true)
|
||||||
sess := s.UserDataDB(uid).NewSession(c).Where(condition, conditionParams...)
|
sess := s.UserDataDB(uid).NewSession(c).Where(condition, conditionParams...)
|
||||||
|
sess = s.appendFilterTagIdsConditionToQuery(sess, uid, maxTransactionTime, minTransactionTime, tagIds, noTags, tagFilterType)
|
||||||
if len(tagIds) > 0 {
|
|
||||||
sess.In("transaction_id", s.getTransactionQueryByTagIdsCondition(uid, maxTransactionTime, minTransactionTime, tagIds))
|
|
||||||
} else if noTags {
|
|
||||||
sess.NotIn("transaction_id", s.getTransactionQueryByAllTagIdsCondition(uid, maxTransactionTime, minTransactionTime))
|
|
||||||
}
|
|
||||||
|
|
||||||
err = sess.OrderBy("transaction_time desc").Find(&transactions)
|
err = sess.OrderBy("transaction_time desc").Find(&transactions)
|
||||||
|
|
||||||
@@ -181,23 +171,18 @@ func (s *TransactionService) GetTransactionByTransactionId(c core.Context, uid i
|
|||||||
|
|
||||||
// GetAllTransactionCount returns total count of transactions
|
// GetAllTransactionCount returns total count of transactions
|
||||||
func (s *TransactionService) GetAllTransactionCount(c core.Context, uid int64) (int64, error) {
|
func (s *TransactionService) GetAllTransactionCount(c core.Context, uid int64) (int64, error) {
|
||||||
return s.GetTransactionCount(c, uid, 0, 0, 0, nil, nil, nil, false, "", "")
|
return s.GetTransactionCount(c, uid, 0, 0, 0, nil, nil, nil, false, models.TRANSACTION_TAG_FILTER_HAS_ANY, "", "")
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTransactionCount returns count of transactions
|
// GetTransactionCount returns count of transactions
|
||||||
func (s *TransactionService) GetTransactionCount(c core.Context, uid int64, maxTransactionTime int64, minTransactionTime int64, transactionType models.TransactionDbType, categoryIds []int64, accountIds []int64, tagIds []int64, noTags bool, amountFilter string, keyword string) (int64, error) {
|
func (s *TransactionService) GetTransactionCount(c core.Context, uid int64, maxTransactionTime int64, minTransactionTime int64, transactionType models.TransactionDbType, categoryIds []int64, accountIds []int64, tagIds []int64, noTags bool, tagFilterType models.TransactionTagFilterType, amountFilter string, keyword string) (int64, error) {
|
||||||
if uid <= 0 {
|
if uid <= 0 {
|
||||||
return 0, errs.ErrUserIdInvalid
|
return 0, errs.ErrUserIdInvalid
|
||||||
}
|
}
|
||||||
|
|
||||||
condition, conditionParams := s.getTransactionQueryCondition(uid, maxTransactionTime, minTransactionTime, transactionType, categoryIds, accountIds, tagIds, amountFilter, keyword, true)
|
condition, conditionParams := s.buildTransactionQueryCondition(uid, maxTransactionTime, minTransactionTime, transactionType, categoryIds, accountIds, tagIds, amountFilter, keyword, true)
|
||||||
sess := s.UserDataDB(uid).NewSession(c).Where(condition, conditionParams...)
|
sess := s.UserDataDB(uid).NewSession(c).Where(condition, conditionParams...)
|
||||||
|
sess = s.appendFilterTagIdsConditionToQuery(sess, uid, maxTransactionTime, minTransactionTime, tagIds, noTags, tagFilterType)
|
||||||
if len(tagIds) > 0 {
|
|
||||||
sess.In("transaction_id", s.getTransactionQueryByTagIdsCondition(uid, maxTransactionTime, minTransactionTime, tagIds))
|
|
||||||
} else if noTags {
|
|
||||||
sess.NotIn("transaction_id", s.getTransactionQueryByAllTagIdsCondition(uid, maxTransactionTime, minTransactionTime))
|
|
||||||
}
|
|
||||||
|
|
||||||
return sess.Count(&models.Transaction{})
|
return sess.Count(&models.Transaction{})
|
||||||
}
|
}
|
||||||
@@ -1753,7 +1738,7 @@ func (s *TransactionService) doCreateTransaction(sess *xorm.Session, transaction
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *TransactionService) getTransactionQueryCondition(uid int64, maxTransactionTime int64, minTransactionTime int64, transactionType models.TransactionDbType, categoryIds []int64, accountIds []int64, tagIds []int64, amountFilter string, keyword string, noDuplicated bool) (string, []any) {
|
func (s *TransactionService) buildTransactionQueryCondition(uid int64, maxTransactionTime int64, minTransactionTime int64, transactionType models.TransactionDbType, categoryIds []int64, accountIds []int64, tagIds []int64, amountFilter string, keyword string, noDuplicated bool) (string, []any) {
|
||||||
condition := "uid=? AND deleted=?"
|
condition := "uid=? AND deleted=?"
|
||||||
conditionParams := make([]any, 0, 16)
|
conditionParams := make([]any, 0, 16)
|
||||||
conditionParams = append(conditionParams, uid)
|
conditionParams = append(conditionParams, uid)
|
||||||
@@ -1909,38 +1894,41 @@ func (s *TransactionService) getTransactionQueryCondition(uid int64, maxTransact
|
|||||||
return condition, conditionParams
|
return condition, conditionParams
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *TransactionService) getTransactionQueryByTagIdsCondition(uid int64, maxTransactionTime int64, minTransactionTime int64, tagIds []int64) *builder.Builder {
|
func (s *TransactionService) appendFilterTagIdsConditionToQuery(sess *xorm.Session, uid int64, maxTransactionTime int64, minTransactionTime int64, tagIds []int64, noTags bool, tagFilterType models.TransactionTagFilterType) *xorm.Session {
|
||||||
if len(tagIds) > 0 {
|
subQueryCondition := builder.And(builder.Eq{"uid": uid}, builder.Eq{"deleted": false})
|
||||||
condition := builder.And(builder.Eq{"uid": uid}, builder.Eq{"deleted": false})
|
|
||||||
|
|
||||||
if maxTransactionTime > 0 {
|
|
||||||
condition = condition.And(builder.Lte{"transaction_time": maxTransactionTime})
|
|
||||||
}
|
|
||||||
|
|
||||||
if minTransactionTime > 0 {
|
|
||||||
condition = condition.And(builder.Gte{"transaction_time": minTransactionTime})
|
|
||||||
}
|
|
||||||
|
|
||||||
condition = condition.And(builder.In("tag_id", tagIds))
|
|
||||||
|
|
||||||
return builder.Select("transaction_id").From("transaction_tag_index").Where(condition)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *TransactionService) getTransactionQueryByAllTagIdsCondition(uid int64, maxTransactionTime int64, minTransactionTime int64) *builder.Builder {
|
|
||||||
condition := builder.And(builder.Eq{"uid": uid}, builder.Eq{"deleted": false})
|
|
||||||
|
|
||||||
if maxTransactionTime > 0 {
|
if maxTransactionTime > 0 {
|
||||||
condition = condition.And(builder.Lte{"transaction_time": maxTransactionTime})
|
subQueryCondition = subQueryCondition.And(builder.Lte{"transaction_time": maxTransactionTime})
|
||||||
}
|
}
|
||||||
|
|
||||||
if minTransactionTime > 0 {
|
if minTransactionTime > 0 {
|
||||||
condition = condition.And(builder.Gte{"transaction_time": minTransactionTime})
|
subQueryCondition = subQueryCondition.And(builder.Gte{"transaction_time": minTransactionTime})
|
||||||
}
|
}
|
||||||
|
|
||||||
return builder.Select("transaction_id").From("transaction_tag_index").Where(condition)
|
if noTags {
|
||||||
|
subQuery := builder.Select("transaction_id").From("transaction_tag_index").Where(subQueryCondition)
|
||||||
|
sess.NotIn("transaction_id", subQuery)
|
||||||
|
return sess
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(tagIds) < 1 {
|
||||||
|
return sess
|
||||||
|
}
|
||||||
|
|
||||||
|
subQueryCondition = subQueryCondition.And(builder.In("tag_id", tagIds))
|
||||||
|
subQuery := builder.Select("transaction_id").From("transaction_tag_index").Where(subQueryCondition)
|
||||||
|
|
||||||
|
if tagFilterType == models.TRANSACTION_TAG_FILTER_HAS_ALL || tagFilterType == models.TRANSACTION_TAG_FILTER_NOT_HAS_ALL {
|
||||||
|
subQuery = subQuery.GroupBy("transaction_id").Having(fmt.Sprintf("COUNT(DISTINCT tag_id) >= %d", len(tagIds)))
|
||||||
|
}
|
||||||
|
|
||||||
|
if tagFilterType == models.TRANSACTION_TAG_FILTER_HAS_ANY || tagFilterType == models.TRANSACTION_TAG_FILTER_HAS_ALL {
|
||||||
|
sess.In("transaction_id", subQuery)
|
||||||
|
} else if tagFilterType == models.TRANSACTION_TAG_FILTER_NOT_HAS_ANY || tagFilterType == models.TRANSACTION_TAG_FILTER_NOT_HAS_ALL {
|
||||||
|
sess.NotIn("transaction_id", subQuery)
|
||||||
|
}
|
||||||
|
|
||||||
|
return sess
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *TransactionService) isAccountIdValid(transaction *models.Transaction) error {
|
func (s *TransactionService) isAccountIdValid(transaction *models.Transaction) error {
|
||||||
|
|||||||
@@ -36,6 +36,27 @@ const allTransactionEditScopeTypes = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const allTransactionTagFilterTypes = {
|
||||||
|
HasAny: {
|
||||||
|
type: 0,
|
||||||
|
name: 'With Any Selected Tags'
|
||||||
|
},
|
||||||
|
HasAll: {
|
||||||
|
type: 1,
|
||||||
|
name: 'With All Selected Tags'
|
||||||
|
},
|
||||||
|
NotHasAny: {
|
||||||
|
type: 2,
|
||||||
|
name: 'Without Any Selected Tags'
|
||||||
|
},
|
||||||
|
NotHasAll: {
|
||||||
|
type: 3,
|
||||||
|
name: 'Without All Selected Tags'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const defaultTransactionTagFilterType = allTransactionTagFilterTypes.HasAny;
|
||||||
|
|
||||||
const minAmountNumber = -99999999999; // -999999999.99
|
const minAmountNumber = -99999999999; // -999999999.99
|
||||||
const maxAmountNumber = 99999999999; // 999999999.99
|
const maxAmountNumber = 99999999999; // 999999999.99
|
||||||
const maxPictureCount = 10;
|
const maxPictureCount = 10;
|
||||||
@@ -43,6 +64,8 @@ const maxPictureCount = 10;
|
|||||||
export default {
|
export default {
|
||||||
allTransactionTypes: allTransactionTypes,
|
allTransactionTypes: allTransactionTypes,
|
||||||
allTransactionEditScopeTypes: allTransactionEditScopeTypes,
|
allTransactionEditScopeTypes: allTransactionEditScopeTypes,
|
||||||
|
allTransactionTagFilterTypes: allTransactionTagFilterTypes,
|
||||||
|
defaultTransactionTagFilterType: defaultTransactionTagFilterType,
|
||||||
minAmountNumber: minAmountNumber,
|
minAmountNumber: minAmountNumber,
|
||||||
maxAmountNumber: maxAmountNumber,
|
maxAmountNumber: maxAmountNumber,
|
||||||
maxPictureCount: maxPictureCount,
|
maxPictureCount: maxPictureCount,
|
||||||
|
|||||||
@@ -1212,6 +1212,25 @@ function getAllTransactionEditScopeTypes(translateFn) {
|
|||||||
return allEditScopeTypes;
|
return allEditScopeTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getAllTransactionTagFilterTypes(translateFn) {
|
||||||
|
const allTagFilterTypes = [];
|
||||||
|
|
||||||
|
for (const typeName in transactionConstants.allTransactionTagFilterTypes) {
|
||||||
|
if (!Object.prototype.hasOwnProperty.call(transactionConstants.allTransactionTagFilterTypes, typeName)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const tagFilterType = transactionConstants.allTransactionTagFilterTypes[typeName];
|
||||||
|
|
||||||
|
allTagFilterTypes.push({
|
||||||
|
type: tagFilterType.type,
|
||||||
|
displayName: translateFn(tagFilterType.name)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return allTagFilterTypes;
|
||||||
|
}
|
||||||
|
|
||||||
function getAllTransactionScheduledFrequencyTypes(translateFn) {
|
function getAllTransactionScheduledFrequencyTypes(translateFn) {
|
||||||
const allScheduledFrequencyTypes = [];
|
const allScheduledFrequencyTypes = [];
|
||||||
|
|
||||||
@@ -1756,6 +1775,7 @@ export function i18nFunctions(i18nGlobal) {
|
|||||||
getAllStatisticsSortingTypes: () => getAllStatisticsSortingTypes(i18nGlobal.t),
|
getAllStatisticsSortingTypes: () => getAllStatisticsSortingTypes(i18nGlobal.t),
|
||||||
getAllStatisticsDateAggregationTypes: () => getAllStatisticsDateAggregationTypes(i18nGlobal.t),
|
getAllStatisticsDateAggregationTypes: () => getAllStatisticsDateAggregationTypes(i18nGlobal.t),
|
||||||
getAllTransactionEditScopeTypes: () => getAllTransactionEditScopeTypes(i18nGlobal.t),
|
getAllTransactionEditScopeTypes: () => getAllTransactionEditScopeTypes(i18nGlobal.t),
|
||||||
|
getAllTransactionTagFilterTypes: () => getAllTransactionTagFilterTypes(i18nGlobal.t),
|
||||||
getAllTransactionScheduledFrequencyTypes: () => getAllTransactionScheduledFrequencyTypes(i18nGlobal.t),
|
getAllTransactionScheduledFrequencyTypes: () => getAllTransactionScheduledFrequencyTypes(i18nGlobal.t),
|
||||||
getAllTransactionDefaultCategories: (categoryType, locale) => getAllTransactionDefaultCategories(categoryType, locale, i18nGlobal.t),
|
getAllTransactionDefaultCategories: (categoryType, locale) => getAllTransactionDefaultCategories(categoryType, locale, i18nGlobal.t),
|
||||||
getAllDisplayExchangeRates: (settingsStore, exchangeRatesData) => getAllDisplayExchangeRates(settingsStore, exchangeRatesData, i18nGlobal.t),
|
getAllDisplayExchangeRates: (settingsStore, exchangeRatesData) => getAllDisplayExchangeRates(settingsStore, exchangeRatesData, i18nGlobal.t),
|
||||||
|
|||||||
+4
-4
@@ -299,15 +299,15 @@ export default {
|
|||||||
id
|
id
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
getTransactions: ({ maxTime, minTime, count, page, withCount, type, categoryIds, accountIds, tagIds, amountFilter, keyword }) => {
|
getTransactions: ({ maxTime, minTime, count, page, withCount, type, categoryIds, accountIds, tagIds, tagFilterType, amountFilter, keyword }) => {
|
||||||
amountFilter = encodeURIComponent(amountFilter);
|
amountFilter = encodeURIComponent(amountFilter);
|
||||||
keyword = encodeURIComponent(keyword);
|
keyword = encodeURIComponent(keyword);
|
||||||
return axios.get(`v1/transactions/list.json?max_time=${maxTime}&min_time=${minTime}&type=${type}&category_ids=${categoryIds}&account_ids=${accountIds}&tag_ids=${tagIds}&amount_filter=${amountFilter}&keyword=${keyword}&count=${count}&page=${page}&with_count=${withCount}&trim_account=true&trim_category=true&trim_tag=true`);
|
return axios.get(`v1/transactions/list.json?max_time=${maxTime}&min_time=${minTime}&type=${type}&category_ids=${categoryIds}&account_ids=${accountIds}&tag_ids=${tagIds}&tag_filter_type=${tagFilterType}&amount_filter=${amountFilter}&keyword=${keyword}&count=${count}&page=${page}&with_count=${withCount}&trim_account=true&trim_category=true&trim_tag=true`);
|
||||||
},
|
},
|
||||||
getAllTransactionsByMonth: ({ year, month, type, categoryIds, accountIds, tagIds, amountFilter, keyword }) => {
|
getAllTransactionsByMonth: ({ year, month, type, categoryIds, accountIds, tagIds, tagFilterType, amountFilter, keyword }) => {
|
||||||
amountFilter = encodeURIComponent(amountFilter);
|
amountFilter = encodeURIComponent(amountFilter);
|
||||||
keyword = encodeURIComponent(keyword);
|
keyword = encodeURIComponent(keyword);
|
||||||
return axios.get(`v1/transactions/list/by_month.json?year=${year}&month=${month}&type=${type}&category_ids=${categoryIds}&account_ids=${accountIds}&tag_ids=${tagIds}&amount_filter=${amountFilter}&keyword=${keyword}&trim_account=true&trim_category=true&trim_tag=true`);
|
return axios.get(`v1/transactions/list/by_month.json?year=${year}&month=${month}&type=${type}&category_ids=${categoryIds}&account_ids=${accountIds}&tag_ids=${tagIds}&tag_filter_type=${tagFilterType}&amount_filter=${amountFilter}&keyword=${keyword}&trim_account=true&trim_category=true&trim_tag=true`);
|
||||||
},
|
},
|
||||||
getTransactionStatistics: ({ startTime, endTime, useTransactionTimezone }) => {
|
getTransactionStatistics: ({ startTime, endTime, useTransactionTimezone }) => {
|
||||||
const queryParams = [];
|
const queryParams = [];
|
||||||
|
|||||||
@@ -1177,6 +1177,7 @@
|
|||||||
"balanceTime": "Balance Time",
|
"balanceTime": "Balance Time",
|
||||||
"startTime": "Start Time",
|
"startTime": "Start Time",
|
||||||
"endTime": "End Time",
|
"endTime": "End Time",
|
||||||
|
"tagFilterType": "Tag Filter Type",
|
||||||
"amountFilter": "Amount Filter",
|
"amountFilter": "Amount Filter",
|
||||||
"sourceAccountId": "Source Account ID",
|
"sourceAccountId": "Source Account ID",
|
||||||
"destinationAccountId": "Destination Account ID",
|
"destinationAccountId": "Destination Account ID",
|
||||||
@@ -1515,6 +1516,10 @@
|
|||||||
"Source Account": "Source Account",
|
"Source Account": "Source Account",
|
||||||
"Destination Account": "Destination Account",
|
"Destination Account": "Destination Account",
|
||||||
"Without Tags": "Without Tags",
|
"Without Tags": "Without Tags",
|
||||||
|
"With Any Selected Tags": "With Any Selected Tags",
|
||||||
|
"With All Selected Tags": "With All Selected Tags",
|
||||||
|
"Without Any Selected Tags": "Without Any Selected Tags",
|
||||||
|
"Without All Selected Tags": "Without All Selected Tags",
|
||||||
"Multiple Tags": "Multiple Tags",
|
"Multiple Tags": "Multiple Tags",
|
||||||
"Transaction Time": "Transaction Time",
|
"Transaction Time": "Transaction Time",
|
||||||
"Scheduled Transaction Frequency": "Scheduled Transaction Frequency",
|
"Scheduled Transaction Frequency": "Scheduled Transaction Frequency",
|
||||||
|
|||||||
@@ -1177,6 +1177,7 @@
|
|||||||
"balanceTime": "Thời gian số dư",
|
"balanceTime": "Thời gian số dư",
|
||||||
"startTime": "Thời gian bắt đầu",
|
"startTime": "Thời gian bắt đầu",
|
||||||
"endTime": "Thời gian kết thúc",
|
"endTime": "Thời gian kết thúc",
|
||||||
|
"tagFilterType": "Tag Filter Type",
|
||||||
"amountFilter": "Bộ lọc số tiền",
|
"amountFilter": "Bộ lọc số tiền",
|
||||||
"sourceAccountId": "ID tài khoản nguồn",
|
"sourceAccountId": "ID tài khoản nguồn",
|
||||||
"destinationAccountId": "ID tài khoản đích",
|
"destinationAccountId": "ID tài khoản đích",
|
||||||
@@ -1515,6 +1516,10 @@
|
|||||||
"Source Account": "Tài khoản nguồn",
|
"Source Account": "Tài khoản nguồn",
|
||||||
"Destination Account": "Tài khoản đích",
|
"Destination Account": "Tài khoản đích",
|
||||||
"Without Tags": "Không có thẻ",
|
"Without Tags": "Không có thẻ",
|
||||||
|
"With Any Selected Tags": "With Any Selected Tags",
|
||||||
|
"With All Selected Tags": "With All Selected Tags",
|
||||||
|
"Without Any Selected Tags": "Without Any Selected Tags",
|
||||||
|
"Without All Selected Tags": "Without All Selected Tags",
|
||||||
"Multiple Tags": "Nhiều thẻ",
|
"Multiple Tags": "Nhiều thẻ",
|
||||||
"Transaction Time": "Thời gian giao dịch",
|
"Transaction Time": "Thời gian giao dịch",
|
||||||
"Scheduled Transaction Frequency": "Tần suất giao dịch theo lịch trình",
|
"Scheduled Transaction Frequency": "Tần suất giao dịch theo lịch trình",
|
||||||
|
|||||||
@@ -1177,6 +1177,7 @@
|
|||||||
"balanceTime": "余额时间",
|
"balanceTime": "余额时间",
|
||||||
"startTime": "开始时间",
|
"startTime": "开始时间",
|
||||||
"endTime": "结束时间",
|
"endTime": "结束时间",
|
||||||
|
"tagFilterType": "标签过滤类型",
|
||||||
"amountFilter": "金额过滤",
|
"amountFilter": "金额过滤",
|
||||||
"sourceAccountId": "来源账户ID",
|
"sourceAccountId": "来源账户ID",
|
||||||
"destinationAccountId": "目标账户ID",
|
"destinationAccountId": "目标账户ID",
|
||||||
@@ -1515,6 +1516,10 @@
|
|||||||
"Source Account": "来源账户",
|
"Source Account": "来源账户",
|
||||||
"Destination Account": "目标账户",
|
"Destination Account": "目标账户",
|
||||||
"Without Tags": "没有标签",
|
"Without Tags": "没有标签",
|
||||||
|
"With Any Selected Tags": "包含任意选中的标签",
|
||||||
|
"With All Selected Tags": "包含全部选中的标签",
|
||||||
|
"Without Any Selected Tags": "不包含任意选中的标签",
|
||||||
|
"Without All Selected Tags": "不包含全部选中的标签",
|
||||||
"Multiple Tags": "多个标签",
|
"Multiple Tags": "多个标签",
|
||||||
"Transaction Time": "交易时间",
|
"Transaction Time": "交易时间",
|
||||||
"Scheduled Transaction Frequency": "定时交易周期",
|
"Scheduled Transaction Frequency": "定时交易周期",
|
||||||
|
|||||||
@@ -104,6 +104,7 @@ const router = createRouter({
|
|||||||
initCategoryIds: route.query.categoryIds,
|
initCategoryIds: route.query.categoryIds,
|
||||||
initAccountIds: route.query.accountIds,
|
initAccountIds: route.query.accountIds,
|
||||||
initTagIds: route.query.tagIds,
|
initTagIds: route.query.tagIds,
|
||||||
|
initTagFilterType: route.query.tagFilterType,
|
||||||
initAmountFilter: route.query.amountFilter,
|
initAmountFilter: route.query.amountFilter,
|
||||||
initKeyword: route.query.keyword
|
initKeyword: route.query.keyword
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -374,6 +374,7 @@ export const useTransactionsStore = defineStore('transactions', {
|
|||||||
categoryIds: '',
|
categoryIds: '',
|
||||||
accountIds: '',
|
accountIds: '',
|
||||||
tagIds: '',
|
tagIds: '',
|
||||||
|
tagFilterType: transactionConstants.defaultTransactionTagFilterType.type,
|
||||||
amountFilter: '',
|
amountFilter: '',
|
||||||
keyword: ''
|
keyword: ''
|
||||||
},
|
},
|
||||||
@@ -671,6 +672,7 @@ export const useTransactionsStore = defineStore('transactions', {
|
|||||||
this.transactionsFilter.categoryIds = '';
|
this.transactionsFilter.categoryIds = '';
|
||||||
this.transactionsFilter.accountIds = '';
|
this.transactionsFilter.accountIds = '';
|
||||||
this.transactionsFilter.tagIds = '';
|
this.transactionsFilter.tagIds = '';
|
||||||
|
this.transactionsFilter.tagFilterType = transactionConstants.defaultTransactionTagFilterType.type;
|
||||||
this.transactionsFilter.amountFilter = '';
|
this.transactionsFilter.amountFilter = '';
|
||||||
this.transactionsFilter.keyword = '';
|
this.transactionsFilter.keyword = '';
|
||||||
this.transactions = [];
|
this.transactions = [];
|
||||||
@@ -725,6 +727,12 @@ export const useTransactionsStore = defineStore('transactions', {
|
|||||||
this.transactionsFilter.tagIds = '';
|
this.transactionsFilter.tagIds = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (filter && isNumber(filter.tagFilterType)) {
|
||||||
|
this.transactionsFilter.tagFilterType = filter.tagFilterType;
|
||||||
|
} else {
|
||||||
|
this.transactionsFilter.tagFilterType = transactionConstants.defaultTransactionTagFilterType.type;
|
||||||
|
}
|
||||||
|
|
||||||
if (filter && isString(filter.amountFilter)) {
|
if (filter && isString(filter.amountFilter)) {
|
||||||
this.transactionsFilter.amountFilter = filter.amountFilter;
|
this.transactionsFilter.amountFilter = filter.amountFilter;
|
||||||
} else {
|
} else {
|
||||||
@@ -775,6 +783,11 @@ export const useTransactionsStore = defineStore('transactions', {
|
|||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (filter && isNumber(filter.tagFilterType) && this.transactionsFilter.tagFilterType !== filter.tagFilterType) {
|
||||||
|
this.transactionsFilter.tagFilterType = filter.tagFilterType;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (filter && isString(filter.amountFilter) && this.transactionsFilter.amountFilter !== filter.amountFilter) {
|
if (filter && isString(filter.amountFilter) && this.transactionsFilter.amountFilter !== filter.amountFilter) {
|
||||||
this.transactionsFilter.amountFilter = filter.amountFilter;
|
this.transactionsFilter.amountFilter = filter.amountFilter;
|
||||||
changed = true;
|
changed = true;
|
||||||
@@ -806,6 +819,10 @@ export const useTransactionsStore = defineStore('transactions', {
|
|||||||
querys.push('tagIds=' + this.transactionsFilter.tagIds);
|
querys.push('tagIds=' + this.transactionsFilter.tagIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.transactionsFilter.tagFilterType) {
|
||||||
|
querys.push('tagFilterType=' + this.transactionsFilter.tagFilterType);
|
||||||
|
}
|
||||||
|
|
||||||
querys.push('dateType=' + this.transactionsFilter.dateType);
|
querys.push('dateType=' + this.transactionsFilter.dateType);
|
||||||
|
|
||||||
if (this.transactionsFilter.dateType === datetimeConstants.allDateRanges.Custom.type) {
|
if (this.transactionsFilter.dateType === datetimeConstants.allDateRanges.Custom.type) {
|
||||||
@@ -846,6 +863,7 @@ export const useTransactionsStore = defineStore('transactions', {
|
|||||||
categoryIds: self.transactionsFilter.categoryIds,
|
categoryIds: self.transactionsFilter.categoryIds,
|
||||||
accountIds: self.transactionsFilter.accountIds,
|
accountIds: self.transactionsFilter.accountIds,
|
||||||
tagIds: self.transactionsFilter.tagIds,
|
tagIds: self.transactionsFilter.tagIds,
|
||||||
|
tagFilterType: self.transactionsFilter.tagFilterType,
|
||||||
amountFilter: self.transactionsFilter.amountFilter,
|
amountFilter: self.transactionsFilter.amountFilter,
|
||||||
keyword: self.transactionsFilter.keyword
|
keyword: self.transactionsFilter.keyword
|
||||||
}).then(response => {
|
}).then(response => {
|
||||||
@@ -922,6 +940,7 @@ export const useTransactionsStore = defineStore('transactions', {
|
|||||||
categoryIds: self.transactionsFilter.categoryIds,
|
categoryIds: self.transactionsFilter.categoryIds,
|
||||||
accountIds: self.transactionsFilter.accountIds,
|
accountIds: self.transactionsFilter.accountIds,
|
||||||
tagIds: self.transactionsFilter.tagIds,
|
tagIds: self.transactionsFilter.tagIds,
|
||||||
|
tagFilterType: self.transactionsFilter.tagFilterType,
|
||||||
amountFilter: self.transactionsFilter.amountFilter,
|
amountFilter: self.transactionsFilter.amountFilter,
|
||||||
keyword: self.transactionsFilter.keyword
|
keyword: self.transactionsFilter.keyword
|
||||||
}).then(response => {
|
}).then(response => {
|
||||||
|
|||||||
@@ -376,6 +376,25 @@
|
|||||||
</div>
|
</div>
|
||||||
</v-list-item-title>
|
</v-list-item-title>
|
||||||
</v-list-item>
|
</v-list-item>
|
||||||
|
|
||||||
|
<v-divider v-if="query.tagIds && query.tagIds !== 'none'" />
|
||||||
|
|
||||||
|
<template :key="filterType.type"
|
||||||
|
v-for="filterType in allTransactionTagFilterTypes"
|
||||||
|
v-if="query.tagIds && query.tagIds !== 'none'">
|
||||||
|
<v-list-item class="text-sm" density="compact"
|
||||||
|
:value="filterType.type"
|
||||||
|
:append-icon="(query.tagFilterType === filterType.type ? icons.check : null)">
|
||||||
|
<v-list-item-title class="cursor-pointer"
|
||||||
|
@click="changeTagFilterType(filterType.type)">
|
||||||
|
<div class="d-flex align-center">
|
||||||
|
<v-icon size="24" :icon="filterType.icon"/>
|
||||||
|
<span class="text-sm ml-3">{{ filterType.displayName }}</span>
|
||||||
|
</div>
|
||||||
|
</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
</template>
|
||||||
|
|
||||||
<template :key="transactionTag.id"
|
<template :key="transactionTag.id"
|
||||||
v-for="transactionTag in allTransactionTags">
|
v-for="transactionTag in allTransactionTags">
|
||||||
<v-divider v-if="!transactionTag.hidden || query.tagIds === transactionTag.id" />
|
<v-divider v-if="!transactionTag.hidden || query.tagIds === transactionTag.id" />
|
||||||
@@ -588,6 +607,10 @@ import {
|
|||||||
mdiPencilBoxOutline,
|
mdiPencilBoxOutline,
|
||||||
mdiArrowLeft,
|
mdiArrowLeft,
|
||||||
mdiArrowRight,
|
mdiArrowRight,
|
||||||
|
mdiPlusBoxMultipleOutline,
|
||||||
|
mdiCheckboxMultipleOutline,
|
||||||
|
mdiMinusBoxMultipleOutline,
|
||||||
|
mdiCloseBoxMultipleOutline,
|
||||||
mdiPound,
|
mdiPound,
|
||||||
mdiTextBoxOutline,
|
mdiTextBoxOutline,
|
||||||
mdiDotsVertical
|
mdiDotsVertical
|
||||||
@@ -609,6 +632,7 @@ export default {
|
|||||||
'initCategoryIds',
|
'initCategoryIds',
|
||||||
'initAccountIds',
|
'initAccountIds',
|
||||||
'initTagIds',
|
'initTagIds',
|
||||||
|
'initTagFilterType',
|
||||||
'initAmountFilter',
|
'initAmountFilter',
|
||||||
'initKeyword'
|
'initKeyword'
|
||||||
],
|
],
|
||||||
@@ -649,6 +673,10 @@ export default {
|
|||||||
modifyBalance: mdiPencilBoxOutline,
|
modifyBalance: mdiPencilBoxOutline,
|
||||||
arrowLeft: mdiArrowLeft,
|
arrowLeft: mdiArrowLeft,
|
||||||
arrowRight: mdiArrowRight,
|
arrowRight: mdiArrowRight,
|
||||||
|
withAnyTags: mdiPlusBoxMultipleOutline,
|
||||||
|
withAllTags: mdiCheckboxMultipleOutline,
|
||||||
|
withoutAnyTags: mdiMinusBoxMultipleOutline,
|
||||||
|
withoutAllTags: mdiCloseBoxMultipleOutline,
|
||||||
tag: mdiPound,
|
tag: mdiPound,
|
||||||
templates: mdiTextBoxOutline,
|
templates: mdiTextBoxOutline,
|
||||||
more: mdiDotsVertical
|
more: mdiDotsVertical
|
||||||
@@ -911,6 +939,26 @@ export default {
|
|||||||
allTransactionTypes() {
|
allTransactionTypes() {
|
||||||
return transactionConstants.allTransactionTypes;
|
return transactionConstants.allTransactionTypes;
|
||||||
},
|
},
|
||||||
|
allTransactionTagFilterTypes() {
|
||||||
|
const allTagFilterTypes = this.$locale.getAllTransactionTagFilterTypes();
|
||||||
|
const allTagFilterTypesWithIcon = [];
|
||||||
|
const tagFilterIconMap = {
|
||||||
|
[transactionConstants.allTransactionTagFilterTypes.HasAny.type]: this.icons.withAnyTags,
|
||||||
|
[transactionConstants.allTransactionTagFilterTypes.HasAll.type]: this.icons.withAllTags,
|
||||||
|
[transactionConstants.allTransactionTagFilterTypes.NotHasAny.type]: this.icons.withoutAnyTags,
|
||||||
|
[transactionConstants.allTransactionTagFilterTypes.NotHasAll.type]: this.icons.withoutAllTags
|
||||||
|
};
|
||||||
|
|
||||||
|
for (let i = 0; i < allTagFilterTypes.length; i++) {
|
||||||
|
allTagFilterTypesWithIcon.push({
|
||||||
|
type: allTagFilterTypes[i].type,
|
||||||
|
displayName: allTagFilterTypes[i].displayName,
|
||||||
|
icon: tagFilterIconMap[allTagFilterTypes[i].type]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return allTagFilterTypesWithIcon;
|
||||||
|
},
|
||||||
allAccounts() {
|
allAccounts() {
|
||||||
return this.accountsStore.allAccountsMap;
|
return this.accountsStore.allAccountsMap;
|
||||||
},
|
},
|
||||||
@@ -985,6 +1033,7 @@ export default {
|
|||||||
categoryIds: this.initCategoryIds,
|
categoryIds: this.initCategoryIds,
|
||||||
accountIds: this.initAccountIds,
|
accountIds: this.initAccountIds,
|
||||||
tagIds: this.initTagIds,
|
tagIds: this.initTagIds,
|
||||||
|
tagFilterType: this.initTagFilterType,
|
||||||
amountFilter: this.initAmountFilter,
|
amountFilter: this.initAmountFilter,
|
||||||
keyword: this.initKeyword
|
keyword: this.initKeyword
|
||||||
});
|
});
|
||||||
@@ -1015,6 +1064,7 @@ export default {
|
|||||||
categoryIds: to.query.categoryIds,
|
categoryIds: to.query.categoryIds,
|
||||||
accountIds: to.query.accountIds,
|
accountIds: to.query.accountIds,
|
||||||
tagIds: to.query.tagIds,
|
tagIds: to.query.tagIds,
|
||||||
|
tagFilterType: to.query.tagFilterType,
|
||||||
amountFilter: to.query.amountFilter,
|
amountFilter: to.query.amountFilter,
|
||||||
keyword: to.query.keyword
|
keyword: to.query.keyword
|
||||||
});
|
});
|
||||||
@@ -1042,6 +1092,7 @@ export default {
|
|||||||
categoryIds: query.categoryIds,
|
categoryIds: query.categoryIds,
|
||||||
accountIds: query.accountIds,
|
accountIds: query.accountIds,
|
||||||
tagIds: query.tagIds,
|
tagIds: query.tagIds,
|
||||||
|
tagFilterType: parseInt(query.tagFilterType) >= 0 ? parseInt(query.tagFilterType) : undefined,
|
||||||
amountFilter: query.amountFilter || '',
|
amountFilter: query.amountFilter || '',
|
||||||
keyword: query.keyword || ''
|
keyword: query.keyword || ''
|
||||||
});
|
});
|
||||||
@@ -1256,6 +1307,22 @@ export default {
|
|||||||
this.$router.push(this.getFilterLinkUrl());
|
this.$router.push(this.getFilterLinkUrl());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
changeTagFilterType(filterType) {
|
||||||
|
if (this.query.tagFilterType === filterType) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const changed = this.transactionsStore.updateTransactionListFilter({
|
||||||
|
tagFilterType: filterType
|
||||||
|
});
|
||||||
|
|
||||||
|
if (changed) {
|
||||||
|
this.loading = true;
|
||||||
|
this.currentPageTransactions = [];
|
||||||
|
this.transactionsStore.clearTransactions();
|
||||||
|
this.$router.push(this.getFilterLinkUrl());
|
||||||
|
}
|
||||||
|
},
|
||||||
changeAmountFilter(filterType) {
|
changeAmountFilter(filterType) {
|
||||||
this.currentAmountFilterType = '';
|
this.currentAmountFilterType = '';
|
||||||
this.amountMenuState = false;
|
this.amountMenuState = false;
|
||||||
|
|||||||
@@ -470,6 +470,21 @@
|
|||||||
<f7-icon class="list-item-checked-icon" f7="checkmark_alt" v-if="query.tagIds && queryAllFilterTagIdsCount > 1"></f7-icon>
|
<f7-icon class="list-item-checked-icon" f7="checkmark_alt" v-if="query.tagIds && queryAllFilterTagIdsCount > 1"></f7-icon>
|
||||||
</template>
|
</template>
|
||||||
</f7-list-item>
|
</f7-list-item>
|
||||||
|
|
||||||
|
<f7-list-item :title="filterType.displayName"
|
||||||
|
:key="filterType.type"
|
||||||
|
v-for="filterType in allTransactionTagFilterTypes"
|
||||||
|
v-if="query.tagIds && query.tagIds !== 'none'"
|
||||||
|
@click="changeTagFilterType(filterType.type)"
|
||||||
|
>
|
||||||
|
<template #after>
|
||||||
|
<f7-icon class="list-item-checked-icon"
|
||||||
|
f7="checkmark_alt"
|
||||||
|
v-if="query.tagFilterType === filterType.type">
|
||||||
|
</f7-icon>
|
||||||
|
</template>
|
||||||
|
</f7-list-item>
|
||||||
|
|
||||||
<f7-list-item :title="transactionTag.name"
|
<f7-list-item :title="transactionTag.name"
|
||||||
:class="{ 'list-item-selected': query.tagIds === transactionTag.id, 'item-in-multiple-selection': queryAllFilterTagIdsCount > 1 && queryAllFilterTagIds[transactionTag.id] }"
|
:class="{ 'list-item-selected': query.tagIds === transactionTag.id, 'item-in-multiple-selection': queryAllFilterTagIdsCount > 1 && queryAllFilterTagIds[transactionTag.id] }"
|
||||||
:key="transactionTag.id"
|
:key="transactionTag.id"
|
||||||
@@ -662,6 +677,9 @@ export default {
|
|||||||
allTransactionTypes() {
|
allTransactionTypes() {
|
||||||
return transactionConstants.allTransactionTypes;
|
return transactionConstants.allTransactionTypes;
|
||||||
},
|
},
|
||||||
|
allTransactionTagFilterTypes() {
|
||||||
|
return this.$locale.getAllTransactionTagFilterTypes();
|
||||||
|
},
|
||||||
allAccounts() {
|
allAccounts() {
|
||||||
return this.accountsStore.allAccountsMap;
|
return this.accountsStore.allAccountsMap;
|
||||||
},
|
},
|
||||||
@@ -979,6 +997,21 @@ export default {
|
|||||||
this.reload(null);
|
this.reload(null);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
changeTagFilterType(filterType) {
|
||||||
|
if (this.query.tagFilterType === filterType) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const changed = this.transactionsStore.updateTransactionListFilter({
|
||||||
|
tagFilterType: filterType
|
||||||
|
});
|
||||||
|
|
||||||
|
this.showMorePopover = false;
|
||||||
|
|
||||||
|
if (changed) {
|
||||||
|
this.reload(null);
|
||||||
|
}
|
||||||
|
},
|
||||||
changeAmountFilter(filterType) {
|
changeAmountFilter(filterType) {
|
||||||
if (this.query.amountFilter === filterType) {
|
if (this.query.amountFilter === filterType) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
Reference in New Issue
Block a user