statistics analysis supports filtering tags
This commit is contained in:
+26
-2
@@ -299,8 +299,20 @@ func (a *TransactionsApi) TransactionStatisticsHandler(c *core.WebContext) (any,
|
|||||||
return nil, errs.ErrClientTimezoneOffsetInvalid
|
return nil, errs.ErrClientTimezoneOffsetInvalid
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var allTagIds []int64
|
||||||
|
noTags := statisticReq.TagIds == "none"
|
||||||
|
|
||||||
|
if !noTags {
|
||||||
|
allTagIds, err = a.getTagIds(statisticReq.TagIds)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Warnf(c, "[transactions.TransactionStatisticsHandler] get transaction tag ids error, because %s", err.Error())
|
||||||
|
return nil, errs.Or(err, errs.ErrOperationFailed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uid := c.GetCurrentUid()
|
uid := c.GetCurrentUid()
|
||||||
totalAmounts, err := a.transactions.GetAccountsAndCategoriesTotalIncomeAndExpense(c, uid, statisticReq.StartTime, statisticReq.EndTime, utcOffset, statisticReq.UseTransactionTimezone)
|
totalAmounts, err := a.transactions.GetAccountsAndCategoriesTotalIncomeAndExpense(c, uid, statisticReq.StartTime, statisticReq.EndTime, allTagIds, noTags, statisticReq.TagFilterType, utcOffset, statisticReq.UseTransactionTimezone)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf(c, "[transactions.TransactionStatisticsHandler] failed to get accounts and categories total income and expense for user \"uid:%d\", because %s", uid, err.Error())
|
log.Errorf(c, "[transactions.TransactionStatisticsHandler] failed to get accounts and categories total income and expense for user \"uid:%d\", because %s", uid, err.Error())
|
||||||
@@ -350,8 +362,20 @@ func (a *TransactionsApi) TransactionStatisticsTrendsHandler(c *core.WebContext)
|
|||||||
return nil, errs.Or(err, errs.ErrOperationFailed)
|
return nil, errs.Or(err, errs.ErrOperationFailed)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var allTagIds []int64
|
||||||
|
noTags := statisticTrendsReq.TagIds == "none"
|
||||||
|
|
||||||
|
if !noTags {
|
||||||
|
allTagIds, err = a.getTagIds(statisticTrendsReq.TagIds)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Warnf(c, "[transactions.TransactionStatisticsTrendsHandler] get transaction tag ids error, because %s", err.Error())
|
||||||
|
return nil, errs.Or(err, errs.ErrOperationFailed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uid := c.GetCurrentUid()
|
uid := c.GetCurrentUid()
|
||||||
allMonthlyTotalAmounts, err := a.transactions.GetAccountsAndCategoriesMonthlyIncomeAndExpense(c, uid, startYear, startMonth, endYear, endMonth, utcOffset, statisticTrendsReq.UseTransactionTimezone)
|
allMonthlyTotalAmounts, err := a.transactions.GetAccountsAndCategoriesMonthlyIncomeAndExpense(c, uid, startYear, startMonth, endYear, endMonth, allTagIds, noTags, statisticTrendsReq.TagFilterType, utcOffset, statisticTrendsReq.UseTransactionTimezone)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf(c, "[transactions.TransactionStatisticsTrendsHandler] failed to get accounts and categories total income and expense for user \"uid:%d\", because %s", uid, err.Error())
|
log.Errorf(c, "[transactions.TransactionStatisticsTrendsHandler] failed to get accounts and categories total income and expense for user \"uid:%d\", because %s", uid, err.Error())
|
||||||
|
|||||||
@@ -201,15 +201,19 @@ type TransactionListInMonthByPageRequest struct {
|
|||||||
|
|
||||||
// TransactionStatisticRequest represents all parameters of transaction statistic request
|
// TransactionStatisticRequest represents all parameters of transaction statistic request
|
||||||
type TransactionStatisticRequest struct {
|
type TransactionStatisticRequest struct {
|
||||||
StartTime int64 `form:"start_time" binding:"min=0"`
|
StartTime int64 `form:"start_time" binding:"min=0"`
|
||||||
EndTime int64 `form:"end_time" binding:"min=0"`
|
EndTime int64 `form:"end_time" binding:"min=0"`
|
||||||
UseTransactionTimezone bool `form:"use_transaction_timezone"`
|
TagIds string `form:"tag_ids"`
|
||||||
|
TagFilterType TransactionTagFilterType `form:"tag_filter_type" binding:"min=0,max=3"`
|
||||||
|
UseTransactionTimezone bool `form:"use_transaction_timezone"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// TransactionStatisticTrendsRequest represents all parameters of transaction statistic trends request
|
// TransactionStatisticTrendsRequest represents all parameters of transaction statistic trends request
|
||||||
type TransactionStatisticTrendsRequest struct {
|
type TransactionStatisticTrendsRequest struct {
|
||||||
YearMonthRangeRequest
|
YearMonthRangeRequest
|
||||||
UseTransactionTimezone bool `form:"use_transaction_timezone"`
|
TagIds string `form:"tag_ids"`
|
||||||
|
TagFilterType TransactionTagFilterType `form:"tag_filter_type" binding:"min=0,max=3"`
|
||||||
|
UseTransactionTimezone bool `form:"use_transaction_timezone"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// TransactionAmountsRequest represents all parameters of transaction amounts request
|
// TransactionAmountsRequest represents all parameters of transaction amounts request
|
||||||
|
|||||||
@@ -1288,7 +1288,7 @@ func (s *TransactionService) GetAccountsTotalIncomeAndExpense(c core.Context, ui
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetAccountsAndCategoriesTotalIncomeAndExpense returns the every accounts and categories total income and expense amount by specific date range
|
// GetAccountsAndCategoriesTotalIncomeAndExpense returns the every accounts and categories total income and expense amount by specific date range
|
||||||
func (s *TransactionService) GetAccountsAndCategoriesTotalIncomeAndExpense(c core.Context, uid int64, startUnixTime int64, endUnixTime int64, utcOffset int16, useTransactionTimezone bool) ([]*models.Transaction, error) {
|
func (s *TransactionService) GetAccountsAndCategoriesTotalIncomeAndExpense(c core.Context, uid int64, startUnixTime int64, endUnixTime int64, tagIds []int64, noTags bool, tagFilterType models.TransactionTagFilterType, utcOffset int16, useTransactionTimezone bool) ([]*models.Transaction, error) {
|
||||||
if uid <= 0 {
|
if uid <= 0 {
|
||||||
return nil, errs.ErrUserIdInvalid
|
return nil, errs.ErrUserIdInvalid
|
||||||
}
|
}
|
||||||
@@ -1336,7 +1336,10 @@ func (s *TransactionService) GetAccountsAndCategoriesTotalIncomeAndExpense(c cor
|
|||||||
finalConditionParams = append(finalConditionParams, maxTransactionTime)
|
finalConditionParams = append(finalConditionParams, maxTransactionTime)
|
||||||
}
|
}
|
||||||
|
|
||||||
err := s.UserDataDB(uid).NewSession(c).Select("category_id, account_id, transaction_time, timezone_utc_offset, amount").Where(finalCondition, finalConditionParams...).Limit(pageCountForLoadTransactionAmounts, 0).OrderBy("transaction_time desc").Find(&transactions)
|
sess := s.UserDataDB(uid).NewSession(c).Select("category_id, account_id, transaction_time, timezone_utc_offset, amount").Where(finalCondition, finalConditionParams...)
|
||||||
|
sess = s.appendFilterTagIdsConditionToQuery(sess, uid, maxTransactionTime, minTransactionTime, tagIds, noTags, tagFilterType)
|
||||||
|
|
||||||
|
err := sess.Limit(pageCountForLoadTransactionAmounts, 0).OrderBy("transaction_time desc").Find(&transactions)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -1394,7 +1397,7 @@ func (s *TransactionService) GetAccountsAndCategoriesTotalIncomeAndExpense(c cor
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetAccountsAndCategoriesMonthlyIncomeAndExpense returns the every accounts monthly income and expense amount by specific date range
|
// GetAccountsAndCategoriesMonthlyIncomeAndExpense returns the every accounts monthly income and expense amount by specific date range
|
||||||
func (s *TransactionService) GetAccountsAndCategoriesMonthlyIncomeAndExpense(c core.Context, uid int64, startYear int32, startMonth int32, endYear int32, endMonth int32, utcOffset int16, useTransactionTimezone bool) (map[int32][]*models.Transaction, error) {
|
func (s *TransactionService) GetAccountsAndCategoriesMonthlyIncomeAndExpense(c core.Context, uid int64, startYear int32, startMonth int32, endYear int32, endMonth int32, tagIds []int64, noTags bool, tagFilterType models.TransactionTagFilterType, utcOffset int16, useTransactionTimezone bool) (map[int32][]*models.Transaction, error) {
|
||||||
if uid <= 0 {
|
if uid <= 0 {
|
||||||
return nil, errs.ErrUserIdInvalid
|
return nil, errs.ErrUserIdInvalid
|
||||||
}
|
}
|
||||||
@@ -1447,7 +1450,10 @@ func (s *TransactionService) GetAccountsAndCategoriesMonthlyIncomeAndExpense(c c
|
|||||||
finalConditionParams = append(finalConditionParams, maxTransactionTime)
|
finalConditionParams = append(finalConditionParams, maxTransactionTime)
|
||||||
}
|
}
|
||||||
|
|
||||||
err := s.UserDataDB(uid).NewSession(c).Select("category_id, account_id, transaction_time, timezone_utc_offset, amount").Where(finalCondition, finalConditionParams...).Limit(pageCountForLoadTransactionAmounts, 0).OrderBy("transaction_time desc").Find(&transactions)
|
sess := s.UserDataDB(uid).NewSession(c).Select("category_id, account_id, transaction_time, timezone_utc_offset, amount").Where(finalCondition, finalConditionParams...)
|
||||||
|
sess = s.appendFilterTagIdsConditionToQuery(sess, uid, maxTransactionTime, minTransactionTime, tagIds, noTags, tagFilterType)
|
||||||
|
|
||||||
|
err := sess.Limit(pageCountForLoadTransactionAmounts, 0).OrderBy("transaction_time desc").Find(&transactions)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
+18
-2
@@ -309,7 +309,7 @@ export default {
|
|||||||
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}&tag_filter_type=${tagFilterType}&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, tagIds, tagFilterType }) => {
|
||||||
const queryParams = [];
|
const queryParams = [];
|
||||||
|
|
||||||
if (startTime) {
|
if (startTime) {
|
||||||
@@ -320,9 +320,17 @@ export default {
|
|||||||
queryParams.push(`end_time=${endTime}`);
|
queryParams.push(`end_time=${endTime}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tagIds) {
|
||||||
|
queryParams.push(`tag_ids=${tagIds}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tagFilterType) {
|
||||||
|
queryParams.push(`tag_filter_type=${tagFilterType}`);
|
||||||
|
}
|
||||||
|
|
||||||
return axios.get(`v1/transactions/statistics.json?use_transaction_timezone=${useTransactionTimezone}` + (queryParams.length ? '&' + queryParams.join('&') : ''));
|
return axios.get(`v1/transactions/statistics.json?use_transaction_timezone=${useTransactionTimezone}` + (queryParams.length ? '&' + queryParams.join('&') : ''));
|
||||||
},
|
},
|
||||||
getTransactionStatisticsTrends: ({ startYearMonth, endYearMonth, useTransactionTimezone }) => {
|
getTransactionStatisticsTrends: ({ startYearMonth, endYearMonth, useTransactionTimezone, tagIds, tagFilterType }) => {
|
||||||
const queryParams = [];
|
const queryParams = [];
|
||||||
|
|
||||||
if (startYearMonth) {
|
if (startYearMonth) {
|
||||||
@@ -333,6 +341,14 @@ export default {
|
|||||||
queryParams.push(`end_year_month=${endYearMonth}`);
|
queryParams.push(`end_year_month=${endYearMonth}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tagIds) {
|
||||||
|
queryParams.push(`tag_ids=${tagIds}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tagFilterType) {
|
||||||
|
queryParams.push(`tag_filter_type=${tagFilterType}`);
|
||||||
|
}
|
||||||
|
|
||||||
return axios.get(`v1/transactions/statistics/trends.json?use_transaction_timezone=${useTransactionTimezone}` + (queryParams.length ? '&' + queryParams.join('&') : ''));
|
return axios.get(`v1/transactions/statistics/trends.json?use_transaction_timezone=${useTransactionTimezone}` + (queryParams.length ? '&' + queryParams.join('&') : ''));
|
||||||
},
|
},
|
||||||
getTransactionAmounts: ({ useTransactionTimezone, today, thisWeek, thisMonth, thisYear, lastMonth, monthBeforeLastMonth, monthBeforeLast2Months, monthBeforeLast3Months, monthBeforeLast4Months, monthBeforeLast5Months, monthBeforeLast6Months, monthBeforeLast7Months, monthBeforeLast8Months, monthBeforeLast9Months, monthBeforeLast10Months }) => {
|
getTransactionAmounts: ({ useTransactionTimezone, today, thisWeek, thisMonth, thisYear, lastMonth, monthBeforeLastMonth, monthBeforeLast2Months, monthBeforeLast3Months, monthBeforeLast4Months, monthBeforeLast5Months, monthBeforeLast6Months, monthBeforeLast7Months, monthBeforeLast8Months, monthBeforeLast9Months, monthBeforeLast10Months }) => {
|
||||||
|
|||||||
@@ -122,6 +122,8 @@ const router = createRouter({
|
|||||||
initEndTime: route.query.endTime,
|
initEndTime: route.query.endTime,
|
||||||
initFilterAccountIds: route.query.filterAccountIds,
|
initFilterAccountIds: route.query.filterAccountIds,
|
||||||
initFilterCategoryIds: route.query.filterCategoryIds,
|
initFilterCategoryIds: route.query.filterCategoryIds,
|
||||||
|
initTagIds: route.query.tagIds,
|
||||||
|
initTagFilterType: route.query.tagFilterType,
|
||||||
initSortingType: route.query.sortingType,
|
initSortingType: route.query.sortingType,
|
||||||
initTrendDateAggregationType: route.query.trendDateAggregationType
|
initTrendDateAggregationType: route.query.trendDateAggregationType
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { useTransactionCategoriesStore } from './transactionCategory.js';
|
|||||||
import { useExchangeRatesStore } from './exchangeRates.js';
|
import { useExchangeRatesStore } from './exchangeRates.js';
|
||||||
|
|
||||||
import datetimeConstants from '@/consts/datetime.js';
|
import datetimeConstants from '@/consts/datetime.js';
|
||||||
|
import transactionConstants from '@/consts/transaction.js';
|
||||||
import statisticsConstants from '@/consts/statistics.js';
|
import statisticsConstants from '@/consts/statistics.js';
|
||||||
import categoryConstants from '@/consts/category.js';
|
import categoryConstants from '@/consts/category.js';
|
||||||
import iconConstants from '@/consts/icon.js';
|
import iconConstants from '@/consts/icon.js';
|
||||||
@@ -16,6 +17,7 @@ import logger from '@/lib/logger.js';
|
|||||||
import {
|
import {
|
||||||
isEquals,
|
isEquals,
|
||||||
isNumber,
|
isNumber,
|
||||||
|
isString,
|
||||||
isObject,
|
isObject,
|
||||||
isInteger,
|
isInteger,
|
||||||
isYearMonth,
|
isYearMonth,
|
||||||
@@ -283,7 +285,9 @@ export const useStatisticsStore = defineStore('statistics', {
|
|||||||
trendChartStartYearMonth: '',
|
trendChartStartYearMonth: '',
|
||||||
trendChartEndYearMonth: '',
|
trendChartEndYearMonth: '',
|
||||||
filterAccountIds: {},
|
filterAccountIds: {},
|
||||||
filterCategoryIds: {}
|
filterCategoryIds: {},
|
||||||
|
tagIds: '',
|
||||||
|
tagFilterType: transactionConstants.defaultTransactionTagFilterType.type
|
||||||
},
|
},
|
||||||
transactionCategoryStatisticsData: {},
|
transactionCategoryStatisticsData: {},
|
||||||
transactionCategoryTrendsData: {},
|
transactionCategoryTrendsData: {},
|
||||||
@@ -560,6 +564,8 @@ export const useStatisticsStore = defineStore('statistics', {
|
|||||||
this.transactionStatisticsFilter.trendChartEndYearMonth = '';
|
this.transactionStatisticsFilter.trendChartEndYearMonth = '';
|
||||||
this.transactionStatisticsFilter.filterAccountIds = {};
|
this.transactionStatisticsFilter.filterAccountIds = {};
|
||||||
this.transactionStatisticsFilter.filterCategoryIds = {};
|
this.transactionStatisticsFilter.filterCategoryIds = {};
|
||||||
|
this.transactionStatisticsFilter.tagIds = '';
|
||||||
|
this.transactionStatisticsFilter.tagFilterType = transactionConstants.defaultTransactionTagFilterType.type;
|
||||||
this.transactionCategoryStatisticsData = {};
|
this.transactionCategoryStatisticsData = {};
|
||||||
this.transactionCategoryTrendsData = {};
|
this.transactionCategoryTrendsData = {};
|
||||||
this.transactionStatisticsStateInvalid = true;
|
this.transactionStatisticsStateInvalid = true;
|
||||||
@@ -679,6 +685,18 @@ export const useStatisticsStore = defineStore('statistics', {
|
|||||||
this.transactionStatisticsFilter.filterCategoryIds = settingsStore.appSettings.statistics.defaultTransactionCategoryFilter || {};
|
this.transactionStatisticsFilter.filterCategoryIds = settingsStore.appSettings.statistics.defaultTransactionCategoryFilter || {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (filter && isString(filter.tagIds)) {
|
||||||
|
this.transactionStatisticsFilter.tagIds = filter.tagIds;
|
||||||
|
} else {
|
||||||
|
this.transactionStatisticsFilter.tagIds = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter && isInteger(filter.tagFilterType)) {
|
||||||
|
this.transactionStatisticsFilter.tagFilterType = filter.tagFilterType;
|
||||||
|
} else {
|
||||||
|
this.transactionStatisticsFilter.tagFilterType = transactionConstants.defaultTransactionTagFilterType.type;
|
||||||
|
}
|
||||||
|
|
||||||
if (filter && isInteger(filter.sortingType)) {
|
if (filter && isInteger(filter.sortingType)) {
|
||||||
this.transactionStatisticsFilter.sortingType = filter.sortingType;
|
this.transactionStatisticsFilter.sortingType = filter.sortingType;
|
||||||
} else {
|
} else {
|
||||||
@@ -747,6 +765,16 @@ export const useStatisticsStore = defineStore('statistics', {
|
|||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (filter && isString(filter.tagIds) && this.transactionStatisticsFilter.tagIds !== filter.tagIds) {
|
||||||
|
this.transactionStatisticsFilter.tagIds = filter.tagIds;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter && isInteger(filter.tagFilterType) && this.transactionStatisticsFilter.tagFilterType !== filter.tagFilterType) {
|
||||||
|
this.transactionStatisticsFilter.tagFilterType = filter.tagFilterType;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (filter && isInteger(filter.sortingType) && this.transactionStatisticsFilter.sortingType !== filter.sortingType) {
|
if (filter && isInteger(filter.sortingType) && this.transactionStatisticsFilter.sortingType !== filter.sortingType) {
|
||||||
this.transactionStatisticsFilter.sortingType = filter.sortingType;
|
this.transactionStatisticsFilter.sortingType = filter.sortingType;
|
||||||
changed = true;
|
changed = true;
|
||||||
@@ -798,6 +826,14 @@ export const useStatisticsStore = defineStore('statistics', {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.transactionStatisticsFilter.tagIds) {
|
||||||
|
querys.push('tagIds=' + this.transactionStatisticsFilter.tagIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.transactionStatisticsFilter.tagFilterType) {
|
||||||
|
querys.push('tagFilterType=' + this.transactionStatisticsFilter.tagFilterType);
|
||||||
|
}
|
||||||
|
|
||||||
querys.push('sortingType=' + this.transactionStatisticsFilter.sortingType);
|
querys.push('sortingType=' + this.transactionStatisticsFilter.sortingType);
|
||||||
|
|
||||||
return querys.join('&');
|
return querys.join('&');
|
||||||
@@ -847,6 +883,14 @@ export const useStatisticsStore = defineStore('statistics', {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.transactionStatisticsFilter.tagIds) {
|
||||||
|
querys.push('tagIds=' + this.transactionStatisticsFilter.tagIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.transactionStatisticsFilter.tagFilterType) {
|
||||||
|
querys.push('tagFilterType=' + this.transactionStatisticsFilter.tagFilterType);
|
||||||
|
}
|
||||||
|
|
||||||
if (analysisType === statisticsConstants.allAnalysisTypes.CategoricalAnalysis
|
if (analysisType === statisticsConstants.allAnalysisTypes.CategoricalAnalysis
|
||||||
&& this.transactionStatisticsFilter.chartDataType !== statisticsConstants.allChartDataTypes.AccountTotalAssets.type
|
&& this.transactionStatisticsFilter.chartDataType !== statisticsConstants.allChartDataTypes.AccountTotalAssets.type
|
||||||
&& this.transactionStatisticsFilter.chartDataType !== statisticsConstants.allChartDataTypes.AccountTotalLiabilities.type) {
|
&& this.transactionStatisticsFilter.chartDataType !== statisticsConstants.allChartDataTypes.AccountTotalLiabilities.type) {
|
||||||
@@ -872,6 +916,8 @@ export const useStatisticsStore = defineStore('statistics', {
|
|||||||
services.getTransactionStatistics({
|
services.getTransactionStatistics({
|
||||||
startTime: self.transactionStatisticsFilter.categoricalChartStartTime,
|
startTime: self.transactionStatisticsFilter.categoricalChartStartTime,
|
||||||
endTime: self.transactionStatisticsFilter.categoricalChartEndTime,
|
endTime: self.transactionStatisticsFilter.categoricalChartEndTime,
|
||||||
|
tagIds: self.transactionStatisticsFilter.tagIds,
|
||||||
|
tagFilterType: self.transactionStatisticsFilter.tagFilterType,
|
||||||
useTransactionTimezone: settingsStore.appSettings.statistics.defaultTimezoneType
|
useTransactionTimezone: settingsStore.appSettings.statistics.defaultTimezoneType
|
||||||
}).then(response => {
|
}).then(response => {
|
||||||
const data = response.data;
|
const data = response.data;
|
||||||
@@ -914,6 +960,8 @@ export const useStatisticsStore = defineStore('statistics', {
|
|||||||
services.getTransactionStatisticsTrends({
|
services.getTransactionStatisticsTrends({
|
||||||
startYearMonth: self.transactionStatisticsFilter.trendChartStartYearMonth,
|
startYearMonth: self.transactionStatisticsFilter.trendChartStartYearMonth,
|
||||||
endYearMonth: self.transactionStatisticsFilter.trendChartEndYearMonth,
|
endYearMonth: self.transactionStatisticsFilter.trendChartEndYearMonth,
|
||||||
|
tagIds: self.transactionStatisticsFilter.tagIds,
|
||||||
|
tagFilterType: self.transactionStatisticsFilter.tagFilterType,
|
||||||
useTransactionTimezone: settingsStore.appSettings.statistics.defaultTimezoneType
|
useTransactionTimezone: settingsStore.appSettings.statistics.defaultTimezoneType
|
||||||
}).then(response => {
|
}).then(response => {
|
||||||
const data = response.data;
|
const data = response.data;
|
||||||
|
|||||||
@@ -76,6 +76,17 @@
|
|||||||
</v-card-text>
|
</v-card-text>
|
||||||
|
|
||||||
<v-card-text :class="{ 'mt-0 mt-sm-2 mt-md-4': dialogMode }" v-else-if="!loading && hasAnyVisibleTag">
|
<v-card-text :class="{ 'mt-0 mt-sm-2 mt-md-4': dialogMode }" v-else-if="!loading && hasAnyVisibleTag">
|
||||||
|
<div class="tag-filter-types d-flex flex-column mb-4" v-if="type === 'statisticsCurrent'">
|
||||||
|
<v-btn border class="justify-start" :key="filterType.type"
|
||||||
|
:color="tagFilterType === filterType.type ? 'primary' : 'default'"
|
||||||
|
:variant="tagFilterType === filterType.type ? 'tonal' : 'outlined'"
|
||||||
|
:append-icon="(tagFilterType === filterType.type ? icons.check : null)"
|
||||||
|
v-for="filterType in allTagFilterTypes"
|
||||||
|
@click="tagFilterType = filterType.type">
|
||||||
|
{{ filterType.displayName }}
|
||||||
|
</v-btn>
|
||||||
|
</div>
|
||||||
|
|
||||||
<v-expansion-panels class="tag-categories" multiple v-model="expandTagCategories">
|
<v-expansion-panels class="tag-categories" multiple v-model="expandTagCategories">
|
||||||
<v-expansion-panel class="border" key="default" value="default">
|
<v-expansion-panel class="border" key="default" value="default">
|
||||||
<v-expansion-panel-title class="expand-panel-title-with-bg py-0">
|
<v-expansion-panel-title class="expand-panel-title-with-bg py-0">
|
||||||
@@ -123,6 +134,9 @@
|
|||||||
import { mapStores } from 'pinia';
|
import { mapStores } from 'pinia';
|
||||||
import { useTransactionTagsStore } from '@/stores/transactionTag.js';
|
import { useTransactionTagsStore } from '@/stores/transactionTag.js';
|
||||||
import { useTransactionsStore } from '@/stores/transaction.js';
|
import { useTransactionsStore } from '@/stores/transaction.js';
|
||||||
|
import { useStatisticsStore } from '@/stores/statistics.js';
|
||||||
|
|
||||||
|
import transactionConstants from '@/consts/transaction.js';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
selectAll,
|
selectAll,
|
||||||
@@ -137,6 +151,7 @@ import {
|
|||||||
mdiEyeOutline,
|
mdiEyeOutline,
|
||||||
mdiEyeOffOutline,
|
mdiEyeOffOutline,
|
||||||
mdiDotsVertical,
|
mdiDotsVertical,
|
||||||
|
mdiCheck,
|
||||||
mdiPound
|
mdiPound
|
||||||
} from '@mdi/js';
|
} from '@mdi/js';
|
||||||
|
|
||||||
@@ -154,6 +169,7 @@ export default {
|
|||||||
loading: true,
|
loading: true,
|
||||||
expandTagCategories: [ 'default' ],
|
expandTagCategories: [ 'default' ],
|
||||||
filterTagIds: {},
|
filterTagIds: {},
|
||||||
|
tagFilterType: transactionConstants.defaultTransactionTagFilterType.type,
|
||||||
showHidden: false,
|
showHidden: false,
|
||||||
icons: {
|
icons: {
|
||||||
selectAll: mdiSelectAll,
|
selectAll: mdiSelectAll,
|
||||||
@@ -162,12 +178,13 @@ export default {
|
|||||||
show: mdiEyeOutline,
|
show: mdiEyeOutline,
|
||||||
hide: mdiEyeOffOutline,
|
hide: mdiEyeOffOutline,
|
||||||
more: mdiDotsVertical,
|
more: mdiDotsVertical,
|
||||||
|
check: mdiCheck,
|
||||||
tag: mdiPound
|
tag: mdiPound
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapStores(useTransactionTagsStore, useTransactionsStore),
|
...mapStores(useTransactionTagsStore, useTransactionsStore, useStatisticsStore),
|
||||||
title() {
|
title() {
|
||||||
return 'Filter Transaction Tags';
|
return 'Filter Transaction Tags';
|
||||||
},
|
},
|
||||||
@@ -177,6 +194,9 @@ export default {
|
|||||||
allTags() {
|
allTags() {
|
||||||
return this.transactionTagsStore.allTransactionTags;
|
return this.transactionTagsStore.allTransactionTags;
|
||||||
},
|
},
|
||||||
|
allTagFilterTypes() {
|
||||||
|
return this.$locale.getAllTransactionTagFilterTypes();
|
||||||
|
},
|
||||||
hasAnyAvailableTag() {
|
hasAnyAvailableTag() {
|
||||||
return this.transactionTagsStore.allAvailableTagsCount > 0;
|
return this.transactionTagsStore.allAvailableTagsCount > 0;
|
||||||
},
|
},
|
||||||
@@ -207,7 +227,20 @@ export default {
|
|||||||
allTransactionTagIds[transactionTag.id] = true;
|
allTransactionTagIds[transactionTag.id] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self.type === 'transactionListCurrent') {
|
if (self.type === 'statisticsCurrent') {
|
||||||
|
let transactionTagIds = self.statisticsStore.transactionStatisticsFilter.tagIds ? self.statisticsStore.transactionStatisticsFilter.tagIds.split(',') : [];
|
||||||
|
|
||||||
|
for (let i = 0; i < transactionTagIds.length; i++) {
|
||||||
|
const transactionTagId = transactionTagIds[i];
|
||||||
|
const transactionTag = self.transactionTagsStore.allTransactionTagsMap[transactionTagId];
|
||||||
|
|
||||||
|
if (transactionTag) {
|
||||||
|
allTransactionTagIds[transactionTag.id] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.filterTagIds = allTransactionTagIds;
|
||||||
|
self.tagFilterType = self.statisticsStore.transactionStatisticsFilter.tagFilterType;
|
||||||
|
} else if (self.type === 'transactionListCurrent') {
|
||||||
for (let transactionTagId in self.transactionsStore.allFilterTagIds) {
|
for (let transactionTagId in self.transactionsStore.allFilterTagIds) {
|
||||||
if (!Object.prototype.hasOwnProperty.call(self.transactionsStore.allFilterTagIds, transactionTagId)) {
|
if (!Object.prototype.hasOwnProperty.call(self.transactionsStore.allFilterTagIds, transactionTagId)) {
|
||||||
continue;
|
continue;
|
||||||
@@ -257,7 +290,16 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.type === 'transactionListCurrent') {
|
if (this.type === 'statisticsCurrent') {
|
||||||
|
changed = self.statisticsStore.updateTransactionStatisticsFilter({
|
||||||
|
tagIds: finalTagIds,
|
||||||
|
tagFilterType: self.tagFilterType
|
||||||
|
});
|
||||||
|
|
||||||
|
if (changed) {
|
||||||
|
self.statisticsStore.updateTransactionStatisticsInvalidState(true);
|
||||||
|
}
|
||||||
|
} else if (this.type === 'transactionListCurrent') {
|
||||||
changed = self.transactionsStore.updateTransactionListFilter({
|
changed = self.transactionsStore.updateTransactionListFilter({
|
||||||
tagIds: finalTagIds
|
tagIds: finalTagIds
|
||||||
});
|
});
|
||||||
@@ -305,6 +347,17 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
.tag-filter-types .v-btn:not(:first-child) {
|
||||||
|
border-top-left-radius: inherit;
|
||||||
|
border-top-right-radius: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag-filter-types .v-btn:not(:last-child) {
|
||||||
|
border-bottom: 0;
|
||||||
|
border-bottom-left-radius: inherit;
|
||||||
|
border-bottom-right-radius: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
.tag-categories .v-expansion-panel-text__wrapper {
|
.tag-categories .v-expansion-panel-text__wrapper {
|
||||||
padding: 0 0 0 20px;
|
padding: 0 0 0 20px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -123,6 +123,9 @@
|
|||||||
<v-list-item :prepend-icon="icons.filter"
|
<v-list-item :prepend-icon="icons.filter"
|
||||||
:title="$t('Filter Transaction Categories')"
|
:title="$t('Filter Transaction Categories')"
|
||||||
@click="showFilterCategoryDialog = true"></v-list-item>
|
@click="showFilterCategoryDialog = true"></v-list-item>
|
||||||
|
<v-list-item :prepend-icon="icons.filter"
|
||||||
|
:title="$t('Filter Transaction Tags')"
|
||||||
|
@click="showFilterTagDialog = true"></v-list-item>
|
||||||
<v-divider class="my-2"/>
|
<v-divider class="my-2"/>
|
||||||
<v-list-item to="/app/settings?tab=statisticsSetting"
|
<v-list-item to="/app/settings?tab=statisticsSetting"
|
||||||
:prepend-icon="icons.filterSettings"
|
:prepend-icon="icons.filterSettings"
|
||||||
@@ -302,6 +305,11 @@
|
|||||||
@settings:change="setCategoryFilter" />
|
@settings:change="setCategoryFilter" />
|
||||||
</v-dialog>
|
</v-dialog>
|
||||||
|
|
||||||
|
<v-dialog width="800" v-model="showFilterTagDialog">
|
||||||
|
<transaction-tag-filter-settings-card type="statisticsCurrent" :dialog-mode="true"
|
||||||
|
@settings:change="setTagFilter" />
|
||||||
|
</v-dialog>
|
||||||
|
|
||||||
<snack-bar ref="snackbar" />
|
<snack-bar ref="snackbar" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -350,11 +358,13 @@ import {
|
|||||||
|
|
||||||
import AccountFilterSettingsCard from '@/views/desktop/common/cards/AccountFilterSettingsCard.vue';
|
import AccountFilterSettingsCard from '@/views/desktop/common/cards/AccountFilterSettingsCard.vue';
|
||||||
import CategoryFilterSettingsCard from '@/views/desktop/common/cards/CategoryFilterSettingsCard.vue';
|
import CategoryFilterSettingsCard from '@/views/desktop/common/cards/CategoryFilterSettingsCard.vue';
|
||||||
|
import TransactionTagFilterSettingsCard from '@/views/desktop/common/cards/TransactionTagFilterSettingsCard.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
AccountFilterSettingsCard,
|
AccountFilterSettingsCard,
|
||||||
CategoryFilterSettingsCard
|
CategoryFilterSettingsCard,
|
||||||
|
TransactionTagFilterSettingsCard
|
||||||
},
|
},
|
||||||
props: [
|
props: [
|
||||||
'initAnalysisType',
|
'initAnalysisType',
|
||||||
@@ -365,6 +375,8 @@ export default {
|
|||||||
'initEndTime',
|
'initEndTime',
|
||||||
'initFilterAccountIds',
|
'initFilterAccountIds',
|
||||||
'initFilterCategoryIds',
|
'initFilterCategoryIds',
|
||||||
|
'initTagIds',
|
||||||
|
'initTagFilterType',
|
||||||
'initSortingType',
|
'initSortingType',
|
||||||
'initTrendDateAggregationType'
|
'initTrendDateAggregationType'
|
||||||
],
|
],
|
||||||
@@ -383,6 +395,7 @@ export default {
|
|||||||
showCustomMonthRangeDialog: false,
|
showCustomMonthRangeDialog: false,
|
||||||
showFilterAccountDialog: false,
|
showFilterAccountDialog: false,
|
||||||
showFilterCategoryDialog: false,
|
showFilterCategoryDialog: false,
|
||||||
|
showFilterTagDialog: false,
|
||||||
icons: {
|
icons: {
|
||||||
check: mdiCheck,
|
check: mdiCheck,
|
||||||
left: mdiArrowLeft,
|
left: mdiArrowLeft,
|
||||||
@@ -599,6 +612,8 @@ export default {
|
|||||||
endTime: this.initEndTime,
|
endTime: this.initEndTime,
|
||||||
filterAccountIds: this.initFilterAccountIds,
|
filterAccountIds: this.initFilterAccountIds,
|
||||||
filterCategoryIds: this.initFilterCategoryIds,
|
filterCategoryIds: this.initFilterCategoryIds,
|
||||||
|
tagIds: this.initTagIds,
|
||||||
|
tagFilterType: this.initTagFilterType,
|
||||||
sortingType: this.initSortingType,
|
sortingType: this.initSortingType,
|
||||||
trendDateAggregationType: this.initTrendDateAggregationType,
|
trendDateAggregationType: this.initTrendDateAggregationType,
|
||||||
});
|
});
|
||||||
@@ -623,6 +638,8 @@ export default {
|
|||||||
endTime: to.query.endTime,
|
endTime: to.query.endTime,
|
||||||
filterAccountIds: to.query.filterAccountIds,
|
filterAccountIds: to.query.filterAccountIds,
|
||||||
filterCategoryIds: to.query.filterCategoryIds,
|
filterCategoryIds: to.query.filterCategoryIds,
|
||||||
|
tagIds: to.query.tagIds,
|
||||||
|
tagFilterType: to.query.tagFilterType,
|
||||||
sortingType: to.query.sortingType,
|
sortingType: to.query.sortingType,
|
||||||
trendDateAggregationType: to.query.trendDateAggregationType
|
trendDateAggregationType: to.query.trendDateAggregationType
|
||||||
});
|
});
|
||||||
@@ -639,6 +656,8 @@ export default {
|
|||||||
chartDataType: query.chartDataType ? parseInt(query.chartDataType) : undefined,
|
chartDataType: query.chartDataType ? parseInt(query.chartDataType) : undefined,
|
||||||
filterAccountIds: query.filterAccountIds ? arrayItemToObjectField(query.filterAccountIds.split(','), true) : {},
|
filterAccountIds: query.filterAccountIds ? arrayItemToObjectField(query.filterAccountIds.split(','), true) : {},
|
||||||
filterCategoryIds: query.filterCategoryIds ? arrayItemToObjectField(query.filterCategoryIds.split(','), true) : {},
|
filterCategoryIds: query.filterCategoryIds ? arrayItemToObjectField(query.filterCategoryIds.split(','), true) : {},
|
||||||
|
tagIds: query.tagIds,
|
||||||
|
tagFilterType: query.tagFilterType && parseInt(query.tagFilterType) >= 0 ? parseInt(query.tagFilterType) : undefined,
|
||||||
sortingType: query.sortingType ? parseInt(query.sortingType) : undefined
|
sortingType: query.sortingType ? parseInt(query.sortingType) : undefined
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1005,6 +1024,15 @@ export default {
|
|||||||
this.$router.push(this.getFilterLinkUrl());
|
this.$router.push(this.getFilterLinkUrl());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
setTagFilter(changed) {
|
||||||
|
this.showFilterTagDialog = false;
|
||||||
|
|
||||||
|
if (changed) {
|
||||||
|
this.loading = true;
|
||||||
|
this.statisticsStore.updateTransactionStatisticsInvalidState(true);
|
||||||
|
this.$router.push(this.getFilterLinkUrl());
|
||||||
|
}
|
||||||
|
},
|
||||||
clickPieChartItem(item) {
|
clickPieChartItem(item) {
|
||||||
this.$router.push(this.getTransactionItemLinkUrl(item.id));
|
this.$router.push(this.getTransactionItemLinkUrl(item.id));
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1092,7 +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,
|
tagFilterType: query.tagFilterType && parseInt(query.tagFilterType) >= 0 ? parseInt(query.tagFilterType) : undefined,
|
||||||
amountFilter: query.amountFilter || '',
|
amountFilter: query.amountFilter || '',
|
||||||
keyword: query.keyword || ''
|
keyword: query.keyword || ''
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -42,6 +42,17 @@
|
|||||||
</f7-list>
|
</f7-list>
|
||||||
|
|
||||||
<f7-block class="combination-list-wrapper margin-vertical" key="default" v-show="!loading && hasAnyVisibleTag">
|
<f7-block class="combination-list-wrapper margin-vertical" key="default" v-show="!loading && hasAnyVisibleTag">
|
||||||
|
<f7-list class="margin-top-half margin-bottom" strong inset dividers v-if="type === 'statisticsCurrent'">
|
||||||
|
<f7-list-item radio
|
||||||
|
:title="filterType.displayName"
|
||||||
|
:value="filterType.type"
|
||||||
|
:checked="tagFilterType === filterType.type"
|
||||||
|
:key="filterType.type"
|
||||||
|
v-for="filterType in allTagFilterTypes"
|
||||||
|
@change="tagFilterType = filterType.type">
|
||||||
|
</f7-list-item>
|
||||||
|
</f7-list>
|
||||||
|
|
||||||
<f7-accordion-item :opened="collapseStates['default'].opened"
|
<f7-accordion-item :opened="collapseStates['default'].opened"
|
||||||
@accordion:open="collapseStates['default'].opened = true"
|
@accordion:open="collapseStates['default'].opened = true"
|
||||||
@accordion:close="collapseStates['default'].opened = false">
|
@accordion:close="collapseStates['default'].opened = false">
|
||||||
@@ -103,6 +114,9 @@
|
|||||||
import { mapStores } from 'pinia';
|
import { mapStores } from 'pinia';
|
||||||
import { useTransactionTagsStore } from '@/stores/transactionTag.js';
|
import { useTransactionTagsStore } from '@/stores/transactionTag.js';
|
||||||
import { useTransactionsStore } from '@/stores/transaction.js';
|
import { useTransactionsStore } from '@/stores/transaction.js';
|
||||||
|
import { useStatisticsStore } from '@/stores/statistics.js';
|
||||||
|
|
||||||
|
import transactionConstants from '@/consts/transaction.js';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
selectAll,
|
selectAll,
|
||||||
@@ -121,6 +135,7 @@ export default {
|
|||||||
loadingError: null,
|
loadingError: null,
|
||||||
type: null,
|
type: null,
|
||||||
filterTagIds: {},
|
filterTagIds: {},
|
||||||
|
tagFilterType: transactionConstants.defaultTransactionTagFilterType.type,
|
||||||
showHidden: false,
|
showHidden: false,
|
||||||
collapseStates: {
|
collapseStates: {
|
||||||
'default': {
|
'default': {
|
||||||
@@ -131,7 +146,7 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapStores(useTransactionTagsStore, useTransactionsStore),
|
...mapStores(useTransactionTagsStore, useTransactionsStore, useStatisticsStore),
|
||||||
title() {
|
title() {
|
||||||
return 'Filter Transaction Tags';
|
return 'Filter Transaction Tags';
|
||||||
},
|
},
|
||||||
@@ -141,6 +156,9 @@ export default {
|
|||||||
allTags() {
|
allTags() {
|
||||||
return this.transactionTagsStore.allTransactionTags;
|
return this.transactionTagsStore.allTransactionTags;
|
||||||
},
|
},
|
||||||
|
allTagFilterTypes() {
|
||||||
|
return this.$locale.getAllTransactionTagFilterTypes();
|
||||||
|
},
|
||||||
hasAnyAvailableTag() {
|
hasAnyAvailableTag() {
|
||||||
return this.transactionTagsStore.allAvailableTagsCount > 0;
|
return this.transactionTagsStore.allAvailableTagsCount > 0;
|
||||||
},
|
},
|
||||||
@@ -174,7 +192,20 @@ export default {
|
|||||||
allTransactionTagIds[transactionTag.id] = true;
|
allTransactionTagIds[transactionTag.id] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self.type === 'transactionListCurrent') {
|
if (self.type === 'statisticsCurrent') {
|
||||||
|
let transactionTagIds = self.statisticsStore.transactionStatisticsFilter.tagIds ? self.statisticsStore.transactionStatisticsFilter.tagIds.split(',') : [];
|
||||||
|
|
||||||
|
for (let i = 0; i < transactionTagIds.length; i++) {
|
||||||
|
const transactionTagId = transactionTagIds[i];
|
||||||
|
const transactionTag = self.transactionTagsStore.allTransactionTagsMap[transactionTagId];
|
||||||
|
|
||||||
|
if (transactionTag) {
|
||||||
|
allTransactionTagIds[transactionTag.id] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.filterTagIds = allTransactionTagIds;
|
||||||
|
self.tagFilterType = self.statisticsStore.transactionStatisticsFilter.tagFilterType;
|
||||||
|
} else if (self.type === 'transactionListCurrent') {
|
||||||
for (let transactionTagId in self.transactionsStore.allFilterTagIds) {
|
for (let transactionTagId in self.transactionsStore.allFilterTagIds) {
|
||||||
if (!Object.prototype.hasOwnProperty.call(self.transactionsStore.allFilterTagIds, transactionTagId)) {
|
if (!Object.prototype.hasOwnProperty.call(self.transactionsStore.allFilterTagIds, transactionTagId)) {
|
||||||
continue;
|
continue;
|
||||||
@@ -210,6 +241,7 @@ export default {
|
|||||||
|
|
||||||
const filteredTagIds = {};
|
const filteredTagIds = {};
|
||||||
let finalTagIds = '';
|
let finalTagIds = '';
|
||||||
|
let changed = true;
|
||||||
|
|
||||||
for (let transactionTagId in self.filterTagIds) {
|
for (let transactionTagId in self.filterTagIds) {
|
||||||
if (!Object.prototype.hasOwnProperty.call(self.filterTagIds, transactionTagId)) {
|
if (!Object.prototype.hasOwnProperty.call(self.filterTagIds, transactionTagId)) {
|
||||||
@@ -229,8 +261,17 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.type === 'transactionListCurrent') {
|
if (this.type === 'statisticsCurrent') {
|
||||||
const changed = self.transactionsStore.updateTransactionListFilter({
|
changed = self.statisticsStore.updateTransactionStatisticsFilter({
|
||||||
|
tagIds: finalTagIds,
|
||||||
|
tagFilterType: self.tagFilterType
|
||||||
|
});
|
||||||
|
|
||||||
|
if (changed) {
|
||||||
|
self.statisticsStore.updateTransactionStatisticsInvalidState(true);
|
||||||
|
}
|
||||||
|
} else if (this.type === 'transactionListCurrent') {
|
||||||
|
changed = self.transactionsStore.updateTransactionListFilter({
|
||||||
tagIds: finalTagIds
|
tagIds: finalTagIds
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -311,6 +311,7 @@
|
|||||||
<f7-actions-group>
|
<f7-actions-group>
|
||||||
<f7-actions-button @click="filterAccounts">{{ $t('Filter Accounts') }}</f7-actions-button>
|
<f7-actions-button @click="filterAccounts">{{ $t('Filter Accounts') }}</f7-actions-button>
|
||||||
<f7-actions-button @click="filterCategories">{{ $t('Filter Transaction Categories') }}</f7-actions-button>
|
<f7-actions-button @click="filterCategories">{{ $t('Filter Transaction Categories') }}</f7-actions-button>
|
||||||
|
<f7-actions-button @click="filterTags">{{ $t('Filter Transaction Tags') }}</f7-actions-button>
|
||||||
</f7-actions-group>
|
</f7-actions-group>
|
||||||
<f7-actions-group>
|
<f7-actions-group>
|
||||||
<f7-actions-button @click="settings">{{ $t('Settings') }}</f7-actions-button>
|
<f7-actions-button @click="settings">{{ $t('Settings') }}</f7-actions-button>
|
||||||
@@ -812,6 +813,9 @@ export default {
|
|||||||
filterCategories() {
|
filterCategories() {
|
||||||
this.f7router.navigate('/settings/filter/category?type=statisticsCurrent');
|
this.f7router.navigate('/settings/filter/category?type=statisticsCurrent');
|
||||||
},
|
},
|
||||||
|
filterTags() {
|
||||||
|
this.f7router.navigate('/settings/filter/tag?type=statisticsCurrent');
|
||||||
|
},
|
||||||
settings() {
|
settings() {
|
||||||
this.f7router.navigate('/statistic/settings');
|
this.f7router.navigate('/statistic/settings');
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -767,7 +767,8 @@ export default {
|
|||||||
type: parseInt(query.type) > 0 ? parseInt(query.type) : undefined,
|
type: parseInt(query.type) > 0 ? parseInt(query.type) : undefined,
|
||||||
categoryIds: query.categoryIds,
|
categoryIds: query.categoryIds,
|
||||||
accountIds: query.accountIds,
|
accountIds: query.accountIds,
|
||||||
tagIds: query.tagIds
|
tagIds: query.tagIds,
|
||||||
|
tagFilterType: query.tagFilterType && parseInt(query.tagFilterType) >= 0 ? parseInt(query.tagFilterType) : undefined
|
||||||
});
|
});
|
||||||
|
|
||||||
this.reload(null);
|
this.reload(null);
|
||||||
|
|||||||
Reference in New Issue
Block a user