mirror of
https://github.com/mayswind/ezbookkeeping.git
synced 2026-05-21 02:04:26 +08:00
allow to filter without tags
This commit is contained in:
+31
-16
@@ -62,14 +62,19 @@ func (a *TransactionsApi) TransactionCountHandler(c *core.Context) (any, *errs.E
|
|||||||
return nil, errs.Or(err, errs.ErrOperationFailed)
|
return nil, errs.Or(err, errs.ErrOperationFailed)
|
||||||
}
|
}
|
||||||
|
|
||||||
allTagIds, err := a.getTagIds(transactionCountReq.TagIds)
|
var allTagIds []int64
|
||||||
|
noTags := transactionCountReq.TagIds == "none"
|
||||||
|
|
||||||
if err != nil {
|
if !noTags {
|
||||||
log.WarnfWithRequestId(c, "[transactions.TransactionCountHandler] get transaction tag ids error, because %s", err.Error())
|
allTagIds, err = a.getTagIds(transactionCountReq.TagIds)
|
||||||
return nil, errs.Or(err, errs.ErrOperationFailed)
|
|
||||||
|
if err != nil {
|
||||||
|
log.WarnfWithRequestId(c, "[transactions.TransactionCountHandler] get transaction tag ids error, because %s", err.Error())
|
||||||
|
return nil, errs.Or(err, errs.ErrOperationFailed)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
totalCount, err := a.transactions.GetTransactionCount(c, uid, transactionCountReq.MaxTime, transactionCountReq.MinTime, transactionCountReq.Type, allCategoryIds, allAccountIds, allTagIds, transactionCountReq.AmountFilter, transactionCountReq.Keyword)
|
totalCount, err := a.transactions.GetTransactionCount(c, uid, transactionCountReq.MaxTime, transactionCountReq.MinTime, transactionCountReq.Type, allCategoryIds, allAccountIds, allTagIds, noTags, transactionCountReq.AmountFilter, transactionCountReq.Keyword)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.ErrorfWithRequestId(c, "[transactions.TransactionCountHandler] failed to get transaction count for user \"uid:%d\", because %s", uid, err.Error())
|
log.ErrorfWithRequestId(c, "[transactions.TransactionCountHandler] failed to get transaction count for user \"uid:%d\", because %s", uid, err.Error())
|
||||||
@@ -125,17 +130,22 @@ func (a *TransactionsApi) TransactionListHandler(c *core.Context) (any, *errs.Er
|
|||||||
return nil, errs.Or(err, errs.ErrOperationFailed)
|
return nil, errs.Or(err, errs.ErrOperationFailed)
|
||||||
}
|
}
|
||||||
|
|
||||||
allTagIds, err := a.getTagIds(transactionListReq.TagIds)
|
var allTagIds []int64
|
||||||
|
noTags := transactionListReq.TagIds == "none"
|
||||||
|
|
||||||
if err != nil {
|
if !noTags {
|
||||||
log.WarnfWithRequestId(c, "[transactions.TransactionListHandler] get transaction tag ids error, because %s", err.Error())
|
allTagIds, err = a.getTagIds(transactionListReq.TagIds)
|
||||||
return nil, errs.Or(err, errs.ErrOperationFailed)
|
|
||||||
|
if err != nil {
|
||||||
|
log.WarnfWithRequestId(c, "[transactions.TransactionListHandler] get transaction tag ids error, because %s", err.Error())
|
||||||
|
return nil, errs.Or(err, errs.ErrOperationFailed)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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, transactionListReq.AmountFilter, transactionListReq.Keyword)
|
totalCount, err = a.transactions.GetTransactionCount(c, uid, transactionListReq.MaxTime, transactionListReq.MinTime, transactionListReq.Type, allCategoryIds, allAccountIds, allTagIds, noTags, transactionListReq.AmountFilter, transactionListReq.Keyword)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.ErrorfWithRequestId(c, "[transactions.TransactionListHandler] failed to get transaction count for user \"uid:%d\", because %s", uid, err.Error())
|
log.ErrorfWithRequestId(c, "[transactions.TransactionListHandler] failed to get transaction count for user \"uid:%d\", because %s", uid, err.Error())
|
||||||
@@ -143,7 +153,7 @@ func (a *TransactionsApi) TransactionListHandler(c *core.Context) (any, *errs.Er
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
transactions, err := a.transactions.GetTransactionsByMaxTime(c, uid, transactionListReq.MaxTime, transactionListReq.MinTime, transactionListReq.Type, allCategoryIds, allAccountIds, allTagIds, 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.AmountFilter, transactionListReq.Keyword, transactionListReq.Page, transactionListReq.Count, true, true)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.ErrorfWithRequestId(c, "[transactions.TransactionListHandler] failed to get transactions earlier than \"%d\" for user \"uid:%d\", because %s", transactionListReq.MaxTime, uid, err.Error())
|
log.ErrorfWithRequestId(c, "[transactions.TransactionListHandler] failed to get transactions earlier than \"%d\" for user \"uid:%d\", because %s", transactionListReq.MaxTime, uid, err.Error())
|
||||||
@@ -223,14 +233,19 @@ func (a *TransactionsApi) TransactionMonthListHandler(c *core.Context) (any, *er
|
|||||||
return nil, errs.Or(err, errs.ErrOperationFailed)
|
return nil, errs.Or(err, errs.ErrOperationFailed)
|
||||||
}
|
}
|
||||||
|
|
||||||
allTagIds, err := a.getTagIds(transactionListReq.TagIds)
|
var allTagIds []int64
|
||||||
|
noTags := transactionListReq.TagIds == "none"
|
||||||
|
|
||||||
if err != nil {
|
if !noTags {
|
||||||
log.WarnfWithRequestId(c, "[transactions.TransactionMonthListHandler] get transaction tag ids error, because %s", err.Error())
|
allTagIds, err = a.getTagIds(transactionListReq.TagIds)
|
||||||
return nil, errs.Or(err, errs.ErrOperationFailed)
|
|
||||||
|
if err != nil {
|
||||||
|
log.WarnfWithRequestId(c, "[transactions.TransactionMonthListHandler] get transaction tag ids error, because %s", err.Error())
|
||||||
|
return nil, errs.Or(err, errs.ErrOperationFailed)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
transactions, err := a.transactions.GetTransactionsInMonthByPage(c, uid, transactionListReq.Year, transactionListReq.Month, transactionListReq.Type, allCategoryIds, allAccountIds, allTagIds, transactionListReq.AmountFilter, transactionListReq.Keyword)
|
transactions, err := a.transactions.GetTransactionsInMonthByPage(c, uid, transactionListReq.Year, transactionListReq.Month, transactionListReq.Type, allCategoryIds, allAccountIds, allTagIds, noTags, transactionListReq.AmountFilter, transactionListReq.Keyword)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.ErrorfWithRequestId(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.ErrorfWithRequestId(c, "[transactions.TransactionMonthListHandler] failed to get transactions in month \"%d-%d\" for user \"uid:%d\", because %s", transactionListReq.Year, transactionListReq.Month, uid, err.Error())
|
||||||
|
|||||||
@@ -74,11 +74,11 @@ func (s *TransactionService) GetAllTransactions(c *core.Context, uid int64, page
|
|||||||
|
|
||||||
// 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, "", "", 1, count, false, noDuplicated)
|
return s.GetTransactionsByMaxTime(c, uid, maxTransactionTime, 0, 0, nil, nil, nil, false, "", "", 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, 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, 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
|
||||||
}
|
}
|
||||||
@@ -107,6 +107,8 @@ func (s *TransactionService) GetTransactionsByMaxTime(c *core.Context, uid int64
|
|||||||
|
|
||||||
if len(tagIds) > 0 {
|
if len(tagIds) > 0 {
|
||||||
sess.In("transaction_id", s.getTransactionQueryByTagIdsCondition(uid, maxTransactionTime, minTransactionTime, tagIds))
|
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)
|
||||||
@@ -115,7 +117,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, 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, amountFilter string, keyword string) ([]*models.Transaction, error) {
|
||||||
if uid <= 0 {
|
if uid <= 0 {
|
||||||
return nil, errs.ErrUserIdInvalid
|
return nil, errs.ErrUserIdInvalid
|
||||||
}
|
}
|
||||||
@@ -133,6 +135,8 @@ func (s *TransactionService) GetTransactionsInMonthByPage(c *core.Context, uid i
|
|||||||
|
|
||||||
if len(tagIds) > 0 {
|
if len(tagIds) > 0 {
|
||||||
sess.In("transaction_id", s.getTransactionQueryByTagIdsCondition(uid, maxTransactionTime, minTransactionTime, tagIds))
|
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)
|
||||||
@@ -176,11 +180,11 @@ func (s *TransactionService) GetTransactionByTransactionId(c *core.Context, uid
|
|||||||
|
|
||||||
// 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, "", "")
|
return s.GetTransactionCount(c, uid, 0, 0, 0, nil, nil, nil, false, "", "")
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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, 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, amountFilter string, keyword string) (int64, error) {
|
||||||
if uid <= 0 {
|
if uid <= 0 {
|
||||||
return 0, errs.ErrUserIdInvalid
|
return 0, errs.ErrUserIdInvalid
|
||||||
}
|
}
|
||||||
@@ -190,6 +194,8 @@ func (s *TransactionService) GetTransactionCount(c *core.Context, uid int64, max
|
|||||||
|
|
||||||
if len(tagIds) > 0 {
|
if len(tagIds) > 0 {
|
||||||
sess.In("transaction_id", s.getTransactionQueryByTagIdsCondition(uid, maxTransactionTime, minTransactionTime, tagIds))
|
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{})
|
||||||
@@ -1535,6 +1541,20 @@ func (s *TransactionService) getTransactionQueryByTagIdsCondition(uid int64, max
|
|||||||
return nil
|
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 {
|
||||||
|
condition = condition.And(builder.Lte{"transaction_time": maxTransactionTime})
|
||||||
|
}
|
||||||
|
|
||||||
|
if minTransactionTime > 0 {
|
||||||
|
condition = condition.And(builder.Gte{"transaction_time": minTransactionTime})
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.Select("transaction_id").From("transaction_tag_index").Where(condition)
|
||||||
|
}
|
||||||
|
|
||||||
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 {
|
||||||
|
|||||||
@@ -1032,6 +1032,7 @@ export default {
|
|||||||
'Multiple Accounts': 'Multiple Accounts',
|
'Multiple Accounts': 'Multiple Accounts',
|
||||||
'Source Account': 'Source Account',
|
'Source Account': 'Source Account',
|
||||||
'Destination Account': 'Destination Account',
|
'Destination Account': 'Destination Account',
|
||||||
|
'Without Tags': 'Without Tags',
|
||||||
'Multiple Tags': 'Multiple Tags',
|
'Multiple Tags': 'Multiple Tags',
|
||||||
'Transaction Time': 'Transaction Time',
|
'Transaction Time': 'Transaction Time',
|
||||||
'Transaction Timezone': 'Transaction Timezone',
|
'Transaction Timezone': 'Transaction Timezone',
|
||||||
|
|||||||
@@ -1032,6 +1032,7 @@ export default {
|
|||||||
'Multiple Accounts': '多个账户',
|
'Multiple Accounts': '多个账户',
|
||||||
'Source Account': '来源账户',
|
'Source Account': '来源账户',
|
||||||
'Destination Account': '目标账户',
|
'Destination Account': '目标账户',
|
||||||
|
'Without Tags': '没有标签',
|
||||||
'Multiple Tags': '多个标签',
|
'Multiple Tags': '多个标签',
|
||||||
'Transaction Time': '交易时间',
|
'Transaction Time': '交易时间',
|
||||||
'Transaction Timezone': '交易时区',
|
'Transaction Timezone': '交易时区',
|
||||||
|
|||||||
@@ -331,6 +331,17 @@
|
|||||||
</div>
|
</div>
|
||||||
</v-list-item-title>
|
</v-list-item-title>
|
||||||
</v-list-item>
|
</v-list-item>
|
||||||
|
<v-list-item key="none" value="none" class="text-sm" density="compact"
|
||||||
|
:class="{ 'list-item-selected': query.tagIds === 'none' }"
|
||||||
|
:append-icon="(query.tagIds === 'none' ? icons.check : null)">
|
||||||
|
<v-list-item-title class="cursor-pointer"
|
||||||
|
@click="changeTagFilter('none')">
|
||||||
|
<div class="d-flex align-center">
|
||||||
|
<v-icon :icon="icons.none" />
|
||||||
|
<span class="text-sm ml-3">{{ $t('Without Tags') }}</span>
|
||||||
|
</div>
|
||||||
|
</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
<v-list-item key="multiple" value="multiple" class="text-sm" density="compact"
|
<v-list-item key="multiple" value="multiple" class="text-sm" density="compact"
|
||||||
:class="{ 'list-item-selected': query.tagIds && queryAllFilterTagIdsCount > 1 }"
|
:class="{ 'list-item-selected': query.tagIds && queryAllFilterTagIdsCount > 1 }"
|
||||||
:append-icon="(query.tagIds && queryAllFilterTagIdsCount > 1 ? icons.check : null)"
|
:append-icon="(query.tagIds && queryAllFilterTagIdsCount > 1 ? icons.check : null)"
|
||||||
@@ -542,6 +553,7 @@ import {
|
|||||||
mdiMagnify,
|
mdiMagnify,
|
||||||
mdiCheck,
|
mdiCheck,
|
||||||
mdiViewGridOutline,
|
mdiViewGridOutline,
|
||||||
|
mdiBorderNoneVariant,
|
||||||
mdiVectorArrangeBelow,
|
mdiVectorArrangeBelow,
|
||||||
mdiRefresh,
|
mdiRefresh,
|
||||||
mdiMenu,
|
mdiMenu,
|
||||||
@@ -600,6 +612,7 @@ export default {
|
|||||||
search: mdiMagnify,
|
search: mdiMagnify,
|
||||||
check: mdiCheck,
|
check: mdiCheck,
|
||||||
all: mdiViewGridOutline,
|
all: mdiViewGridOutline,
|
||||||
|
none: mdiBorderNoneVariant,
|
||||||
multiple: mdiVectorArrangeBelow,
|
multiple: mdiVectorArrangeBelow,
|
||||||
refresh: mdiRefresh,
|
refresh: mdiRefresh,
|
||||||
menu: mdiMenu,
|
menu: mdiMenu,
|
||||||
|
|||||||
@@ -452,6 +452,11 @@
|
|||||||
<f7-icon class="list-item-checked-icon" f7="checkmark_alt" v-if="!query.tagIds"></f7-icon>
|
<f7-icon class="list-item-checked-icon" f7="checkmark_alt" v-if="!query.tagIds"></f7-icon>
|
||||||
</template>
|
</template>
|
||||||
</f7-list-item>
|
</f7-list-item>
|
||||||
|
<f7-list-item :class="{ 'list-item-selected': query.tagIds === 'none' }" :title="$t('Without Tags')" @click="changeTagFilter('none')">
|
||||||
|
<template #after>
|
||||||
|
<f7-icon class="list-item-checked-icon" f7="checkmark_alt" v-if="query.tagIds === 'none'"></f7-icon>
|
||||||
|
</template>
|
||||||
|
</f7-list-item>
|
||||||
<f7-list-item :class="{ 'list-item-selected': query.tagIds && queryAllFilterTagIdsCount > 1 }"
|
<f7-list-item :class="{ 'list-item-selected': query.tagIds && queryAllFilterTagIdsCount > 1 }"
|
||||||
:title="$t('Multiple Tags')" @click="filterMultipleTags()" v-if="allAvailableTagsCount > 0">
|
:title="$t('Multiple Tags')" @click="filterMultipleTags()" v-if="allAvailableTagsCount > 0">
|
||||||
<template #after>
|
<template #after>
|
||||||
|
|||||||
Reference in New Issue
Block a user