transaction list page supports filtering by primary category

This commit is contained in:
MaysWind
2021-01-31 00:25:01 +08:00
parent 063dcde458
commit 00b08a85ad
3 changed files with 122 additions and 24 deletions
+46 -6
View File
@@ -13,15 +13,17 @@ import (
// TransactionsApi represents transaction api
type TransactionsApi struct {
transactions *services.TransactionService
transactionTags *services.TransactionTagService
transactions *services.TransactionService
transactionCategories *services.TransactionCategoryService
transactionTags *services.TransactionTagService
}
// Initialize a transaction api singleton instance
var (
Transactions = &TransactionsApi{
transactions: services.Transactions,
transactionTags: services.TransactionTags,
transactions: services.Transactions,
transactionCategories: services.TransactionCategories,
transactionTags: services.TransactionTags,
}
)
@@ -36,7 +38,26 @@ func (a *TransactionsApi) TransactionListHandler(c *core.Context) (interface{},
}
uid := c.GetCurrentUid()
transactions, err := a.transactions.GetTransactionsByMaxTime(uid, transactionListReq.MaxTime, transactionListReq.MinTime, transactionListReq.Type, transactionListReq.CategoryId, transactionListReq.AccountId, transactionListReq.Keyword, transactionListReq.Count+1, true)
var allCategoryIds []int64
if transactionListReq.CategoryId > 0 {
allSubCategories, err := a.transactionCategories.GetAllCategoriesByUid(uid, 0, transactionListReq.CategoryId)
if err != nil {
log.WarnfWithRequestId(c, "[transactions.TransactionListHandler] get transaction category error, because %s", err.Error())
return nil, errs.ErrOperationFailed
}
if len(allSubCategories) > 0 {
for i := 0; i < len(allSubCategories); i++ {
allCategoryIds = append(allCategoryIds, allSubCategories[i].CategoryId)
}
} else {
allCategoryIds = append(allCategoryIds, transactionListReq.CategoryId)
}
}
transactions, err := a.transactions.GetTransactionsByMaxTime(uid, transactionListReq.MaxTime, transactionListReq.MinTime, transactionListReq.Type, allCategoryIds, transactionListReq.AccountId, transactionListReq.Keyword, transactionListReq.Count+1, true)
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())
@@ -108,7 +129,26 @@ func (a *TransactionsApi) TransactionMonthListHandler(c *core.Context) (interfac
}
uid := c.GetCurrentUid()
transactions, err := a.transactions.GetTransactionsInMonthByPage(uid, transactionListReq.Year, transactionListReq.Month, transactionListReq.Type, transactionListReq.CategoryId, transactionListReq.AccountId, transactionListReq.Keyword, transactionListReq.Page, transactionListReq.Count)
var allCategoryIds []int64
if transactionListReq.CategoryId > 0 {
allSubCategories, err := a.transactionCategories.GetAllCategoriesByUid(uid, 0, transactionListReq.CategoryId)
if err != nil {
log.WarnfWithRequestId(c, "[transactions.TransactionMonthListHandler] get transaction category error, because %s", err.Error())
return nil, errs.ErrOperationFailed
}
if len(allSubCategories) > 0 {
for i := 0; i < len(allSubCategories); i++ {
allCategoryIds = append(allCategoryIds, allSubCategories[i].CategoryId)
}
} else {
allCategoryIds = append(allCategoryIds, transactionListReq.CategoryId)
}
}
transactions, err := a.transactions.GetTransactionsInMonthByPage(uid, transactionListReq.Year, transactionListReq.Month, transactionListReq.Type, allCategoryIds, transactionListReq.AccountId, transactionListReq.Keyword, transactionListReq.Page, transactionListReq.Count)
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())
+30 -9
View File
@@ -2,6 +2,7 @@ package services
import (
"fmt"
"strings"
"time"
"xorm.io/xorm"
@@ -33,11 +34,11 @@ var (
// GetAllTransactionsByMaxTime returns all transactions before given time
func (s *TransactionService) GetAllTransactionsByMaxTime(uid int64, maxTime int64, count int, noDuplicated bool) ([]*models.Transaction, error) {
return s.GetTransactionsByMaxTime(uid, maxTime, 0, 0, 0, 0, "", count, noDuplicated)
return s.GetTransactionsByMaxTime(uid, maxTime, 0, 0, nil, 0, "", count, noDuplicated)
}
// GetTransactionsByMaxTime returns transactions before given time
func (s *TransactionService) GetTransactionsByMaxTime(uid int64, maxTime int64, minTime int64, transactionType models.TransactionDbType, categoryId int64, accountId int64, keyword string, count int, noDuplicated bool) ([]*models.Transaction, error) {
func (s *TransactionService) GetTransactionsByMaxTime(uid int64, maxTime int64, minTime int64, transactionType models.TransactionDbType, categoryIds []int64, accountId int64, keyword string, count int, noDuplicated bool) ([]*models.Transaction, error) {
if uid <= 0 {
return nil, errs.ErrUserIdInvalid
}
@@ -76,9 +77,19 @@ func (s *TransactionService) GetTransactionsByMaxTime(uid int64, maxTime int64,
}
}
if categoryId > 0 {
condition = condition + " AND category_id=?"
conditionParams = append(conditionParams, categoryId)
if len(categoryIds) > 0 {
var conditions strings.Builder
for i := 0; i < len(categoryIds); i++ {
if i > 0 {
conditions.WriteString(",")
}
conditions.WriteString("?")
conditionParams = append(conditionParams, categoryIds[i])
}
condition = condition + " AND category_id IN (" + conditions.String() + ")"
}
if accountId > 0 {
@@ -107,7 +118,7 @@ func (s *TransactionService) GetTransactionsByMaxTime(uid int64, maxTime int64,
}
// GetTransactionsInMonthByPage returns transactions in given year and month
func (s *TransactionService) GetTransactionsInMonthByPage(uid int64, year int, month int, transactionType models.TransactionDbType, categoryId int64, accountId int64, keyword string, page int, count int) ([]*models.Transaction, error) {
func (s *TransactionService) GetTransactionsInMonthByPage(uid int64, year int, month int, transactionType models.TransactionDbType, categoryIds []int64, accountId int64, keyword string, page int, count int) ([]*models.Transaction, error) {
if uid <= 0 {
return nil, errs.ErrUserIdInvalid
}
@@ -162,9 +173,19 @@ func (s *TransactionService) GetTransactionsInMonthByPage(uid int64, year int, m
}
}
if categoryId > 0 {
condition = condition + " AND category_id=?"
conditionParams = append(conditionParams, categoryId)
if len(categoryIds) > 0 {
var conditions strings.Builder
for i := 0; i < len(categoryIds); i++ {
if i > 0 {
conditions.WriteString(",")
}
conditions.WriteString("?")
conditionParams = append(conditionParams, categoryIds[i])
}
condition = condition + " AND category_id IN (" + conditions.String() + ")"
}
if accountId > 0 {
+46 -9
View File
@@ -277,26 +277,44 @@
<f7-popover class="category-popover-menu" :opened="showCategoryPopover"
@popover:opened="showCategoryPopover = true" @popover:closed="showCategoryPopover = false">
<f7-list>
<f7-list accordion-list>
<f7-list-item :title="$t('All')" @click="changeCategoryFilter('0')">
<f7-icon slot="media" f7="rectangle_badge_checkmark"></f7-icon>
<f7-icon slot="after" class="list-item-checked" f7="checkmark_alt" v-if="query.categoryId === '0'"></f7-icon>
</f7-list-item>
<f7-list-item v-for="category in allCategories"
v-show="category.parentId > 0 && (!query.type || category.type === query.type - 1)"
<f7-list-item accordion-item
v-for="category in allPrimaryCategories"
v-show="!query.type || category.type === query.type - 1"
:key="category.id"
:title="category.name"
@click="changeCategoryFilter(category.id)"
>
<f7-icon slot="media"
:icon="category.icon | categoryIcon"
:style="category.color | categoryIconStyle('var(--default-icon-color)')">
</f7-icon>
<f7-icon slot="after"
class="list-item-checked"
f7="checkmark_alt"
v-if="query.categoryId === category.id">
</f7-icon>
<f7-accordion-content>
<f7-list class="padding-left">
<f7-list-item :title="$t('All')" @click="changeCategoryFilter(category.id)">
<f7-icon slot="media" f7="rectangle_badge_checkmark"></f7-icon>
<f7-icon slot="after" class="list-item-checked" f7="checkmark_alt" v-if="query.categoryId === category.id"></f7-icon>
</f7-list-item>
<f7-list-item v-for="subCategory in category.subCategories"
:key="subCategory.id"
:title="subCategory.name"
@click="changeCategoryFilter(subCategory.id)"
>
<f7-icon slot="media"
:icon="subCategory.icon | categoryIcon"
:style="subCategory.color | categoryIconStyle('var(--default-icon-color)')">
</f7-icon>
<f7-icon slot="after"
class="list-item-checked"
f7="checkmark_alt"
v-if="query.categoryId === subCategory.id">
</f7-icon>
</f7-list-item>
</f7-list>
</f7-accordion-content>
</f7-list-item>
</f7-list>
</f7-popover>
@@ -388,6 +406,25 @@ export default {
allCategories() {
return this.$store.state.allTransactionCategoriesMap;
},
allPrimaryCategories() {
const primaryCategories = [];
for (let categoryId in this.$store.state.allTransactionCategoriesMap) {
if (!Object.prototype.hasOwnProperty.call(this.$store.state.allTransactionCategoriesMap, categoryId)) {
continue;
}
const category = this.$store.state.allTransactionCategoriesMap[categoryId];
if (category.parentId !== '0') {
continue;
}
primaryCategories.push(category);
}
return primaryCategories;
},
allDateRanges() {
return this.$constants.datetime.allDateRanges;
}