transaction list page supports filtering by primary category
This commit is contained in:
+46
-6
@@ -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())
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user