Files
ezbookkeeping/src/stores/statistics.js
T

945 lines
47 KiB
JavaScript

import { defineStore } from 'pinia';
import { useSettingsStore } from './setting.js';
import { useUserStore } from './user.js';
import { useAccountsStore } from './account.js';
import { useTransactionCategoriesStore } from './transactionCategory.js';
import { useExchangeRatesStore } from './exchangeRates.js';
import datetimeConstants from '@/consts/datetime.js';
import statisticsConstants from '@/consts/statistics.js';
import categoryConstants from '@/consts/category.js';
import iconConstants from '@/consts/icon.js';
import colorConstants from '@/consts/color.js';
import services from '@/lib/services.js';
import logger from '@/lib/logger.js';
import {
isEquals,
isNumber,
isObject,
isInteger,
isYearMonth,
isYearMonthEquals,
isObjectEmpty,
objectFieldToArrayItem
} from '@/lib/common.js';
import {
getYearAndMonthFromUnixTime,
getDateRangeByDateType
} from '@/lib/datetime.js';
import {
getFinalAccountIdsByFilteredAccountIds
} from '@/lib/account.js';
import {
getFinalCategoryIdsByFilteredCategoryIds
} from '@/lib/category.js';
import {
sortStatisticsItems
} from '@/lib/statistics.js';
function assembleAccountAndCategoryInfo(userStore, accountsStore, transactionCategoriesStore, exchangeRatesStore, items) {
const finalItems = [];
const defaultCurrency = userStore.currentUserDefaultCurrency;
for (let i = 0; i < items.length; i++) {
const dataItem = items[i];
const item = {
categoryId: dataItem.categoryId,
accountId: dataItem.accountId,
amount: dataItem.amount
};
if (item.accountId) {
item.account = accountsStore.allAccountsMap[item.accountId];
}
if (item.account && item.account.parentId !== '0') {
item.primaryAccount = accountsStore.allAccountsMap[item.account.parentId];
} else {
item.primaryAccount = item.account;
}
if (item.categoryId) {
item.category = transactionCategoriesStore.allTransactionCategoriesMap[item.categoryId];
}
if (item.category && item.category.parentId !== '0') {
item.primaryCategory = transactionCategoriesStore.allTransactionCategoriesMap[item.category.parentId];
} else {
item.primaryCategory = item.category;
}
if (item.account && item.account.currency !== defaultCurrency) {
const amount = exchangeRatesStore.getExchangedAmount(item.amount, item.account.currency, defaultCurrency);
if (isNumber(amount)) {
item.amountInDefaultCurrency = Math.floor(amount);
}
} else if (item.account && item.account.currency === defaultCurrency) {
item.amountInDefaultCurrency = item.amount;
} else {
item.amountInDefaultCurrency = null;
}
finalItems.push(item);
}
return finalItems;
}
function getCategoryTotalAmountItems(items, transactionStatisticsFilter) {
const allDataItems = {};
let totalAmount = 0;
let totalNonNegativeAmount = 0;
for (let i = 0; i < items.length; i++) {
const item = items[i];
if (!item.primaryAccount || !item.account || !item.primaryCategory || !item.category) {
continue;
}
if (transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.ExpenseByAccount.type ||
transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.ExpenseByPrimaryCategory.type ||
transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.ExpenseBySecondaryCategory.type ||
transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.TotalExpense.type) {
if (item.category.type !== categoryConstants.allCategoryTypes.Expense) {
continue;
}
} else if (transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.IncomeByAccount.type ||
transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.IncomeByPrimaryCategory.type ||
transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.IncomeBySecondaryCategory.type ||
transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.TotalIncome.type) {
if (item.category.type !== categoryConstants.allCategoryTypes.Income) {
continue;
}
} else if (transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.TotalBalance.type) {
// Do Nothing
} else {
continue;
}
if (transactionStatisticsFilter.filterAccountIds && transactionStatisticsFilter.filterAccountIds[item.account.id]) {
continue;
}
if (transactionStatisticsFilter.filterCategoryIds && transactionStatisticsFilter.filterCategoryIds[item.category.id]) {
continue;
}
if (transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.ExpenseByAccount.type ||
transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.IncomeByAccount.type) {
if (isNumber(item.amountInDefaultCurrency)) {
let data = allDataItems[item.account.id];
if (data) {
data.totalAmount += item.amountInDefaultCurrency;
} else {
data = {
name: item.account.name,
type: 'account',
id: item.account.id,
icon: item.account.icon || iconConstants.defaultAccountIcon.icon,
color: item.account.color || colorConstants.defaultAccountColor,
hidden: item.primaryAccount.hidden || item.account.hidden,
displayOrders: [item.primaryAccount.category, item.primaryAccount.displayOrder, item.account.displayOrder],
totalAmount: item.amountInDefaultCurrency
}
}
totalAmount += item.amountInDefaultCurrency;
if (item.amountInDefaultCurrency > 0) {
totalNonNegativeAmount += item.amountInDefaultCurrency;
}
allDataItems[item.account.id] = data;
}
} else if (transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.ExpenseByPrimaryCategory.type ||
transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.IncomeByPrimaryCategory.type) {
if (isNumber(item.amountInDefaultCurrency)) {
let data = allDataItems[item.primaryCategory.id];
if (data) {
data.totalAmount += item.amountInDefaultCurrency;
} else {
data = {
name: item.primaryCategory.name,
type: 'category',
id: item.primaryCategory.id,
icon: item.primaryCategory.icon || iconConstants.defaultCategoryIcon.icon,
color: item.primaryCategory.color || colorConstants.defaultCategoryColor,
hidden: item.primaryCategory.hidden,
displayOrders: [item.primaryCategory.type, item.primaryCategory.displayOrder],
totalAmount: item.amountInDefaultCurrency
}
}
totalAmount += item.amountInDefaultCurrency;
if (item.amountInDefaultCurrency > 0) {
totalNonNegativeAmount += item.amountInDefaultCurrency;
}
allDataItems[item.primaryCategory.id] = data;
}
} else if (transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.ExpenseBySecondaryCategory.type ||
transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.IncomeBySecondaryCategory.type) {
if (isNumber(item.amountInDefaultCurrency)) {
let data = allDataItems[item.category.id];
if (data) {
data.totalAmount += item.amountInDefaultCurrency;
} else {
data = {
name: item.category.name,
type: 'category',
id: item.category.id,
icon: item.category.icon || iconConstants.defaultCategoryIcon.icon,
color: item.category.color || colorConstants.defaultCategoryColor,
hidden: item.primaryCategory.hidden || item.category.hidden,
displayOrders: [item.primaryCategory.type, item.primaryCategory.displayOrder, item.category.displayOrder],
totalAmount: item.amountInDefaultCurrency
}
}
totalAmount += item.amountInDefaultCurrency;
if (item.amountInDefaultCurrency > 0) {
totalNonNegativeAmount += item.amountInDefaultCurrency;
}
allDataItems[item.category.id] = data;
}
} else if (transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.TotalExpense.type ||
transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.TotalIncome.type ||
transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.TotalBalance.type) {
if (isNumber(item.amountInDefaultCurrency)) {
let data = allDataItems['total'];
let amount = item.amountInDefaultCurrency;
if (transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.TotalBalance.type &&
item.category.type === categoryConstants.allCategoryTypes.Expense) {
amount = -amount;
}
if (data) {
data.totalAmount += amount;
} else {
let name = '';
if (transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.TotalExpense.type) {
name = statisticsConstants.allChartDataTypes.TotalExpense.name;
} else if (transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.TotalIncome.type) {
name = statisticsConstants.allChartDataTypes.TotalIncome.name;
} else if (transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.TotalBalance.type) {
name = statisticsConstants.allChartDataTypes.TotalBalance.name;
}
data = {
name: name,
type: 'total',
id: 'total',
icon: '',
color: '',
hidden: false,
displayOrders: [1],
totalAmount: amount
}
}
totalAmount += amount;
if (item.amountInDefaultCurrency > 0) {
totalNonNegativeAmount += amount;
}
allDataItems['total'] = data;
}
}
}
return {
totalAmount: totalAmount,
totalNonNegativeAmount: totalNonNegativeAmount,
items: allDataItems
};
}
function sortCategoryTotalAmountItems(items, transactionStatisticsFilter) {
sortStatisticsItems(items, transactionStatisticsFilter.sortingType)
}
export const useStatisticsStore = defineStore('statistics', {
state: () => ({
transactionStatisticsFilter: {
chartDataType: statisticsConstants.defaultChartDataType,
categoricalChartType: statisticsConstants.defaultCategoricalChartType,
categoricalChartDateType: statisticsConstants.defaultCategoricalChartDataRangeType,
categoricalChartStartTime: 0,
categoricalChartEndTime: 0,
trendChartType: statisticsConstants.defaultTrendChartType,
trendChartDateType: statisticsConstants.defaultTrendChartDataRangeType,
trendChartStartYearMonth: '',
trendChartEndYearMonth: '',
filterAccountIds: {},
filterCategoryIds: {}
},
transactionCategoryStatisticsData: {},
transactionCategoryTrendsData: {},
transactionStatisticsStateInvalid: true
}),
getters: {
categoricalAnalysisChartDataCategory(state) {
if (state.transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.ExpenseByAccount.type ||
state.transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.IncomeByAccount.type ||
state.transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.AccountTotalAssets.type ||
state.transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.AccountTotalLiabilities.type) {
return 'account';
} else if (state.transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.ExpenseByPrimaryCategory.type ||
state.transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.ExpenseBySecondaryCategory.type ||
state.transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.IncomeByPrimaryCategory.type ||
state.transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.IncomeBySecondaryCategory.type) {
return 'category';
} else {
return '';
}
},
transactionCategoryStatisticsDataWithCategoryAndAccountInfo(state) {
const statistics = state.transactionCategoryStatisticsData;
const finalStatistics = {
startTime: statistics.startTime,
endTime: statistics.endTime,
items: []
};
if (statistics && statistics.items && statistics.items.length) {
const userStore = useUserStore();
const accountsStore = useAccountsStore();
const transactionCategoriesStore = useTransactionCategoriesStore();
const exchangeRatesStore = useExchangeRatesStore();
finalStatistics.items = assembleAccountAndCategoryInfo(userStore, accountsStore, transactionCategoriesStore, exchangeRatesStore, statistics.items);
}
return finalStatistics;
},
transactionCategoryTotalAmountAnalysisData(state) {
if (!state.transactionCategoryStatisticsDataWithCategoryAndAccountInfo || !state.transactionCategoryStatisticsDataWithCategoryAndAccountInfo.items) {
return null;
}
return getCategoryTotalAmountItems(state.transactionCategoryStatisticsDataWithCategoryAndAccountInfo.items, state.transactionStatisticsFilter);
},
accountTotalAmountAnalysisData(state) {
const userStore = useUserStore();
const accountsStore = useAccountsStore();
const exchangeRatesStore = useExchangeRatesStore();
if (!accountsStore.allPlainAccounts) {
return null;
}
const allDataItems = {};
let totalAmount = 0;
let totalNonNegativeAmount = 0;
for (let i = 0; i < accountsStore.allPlainAccounts.length; i++) {
const account = accountsStore.allPlainAccounts[i];
if (state.transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.AccountTotalAssets.type) {
if (!account.isAsset) {
continue;
}
} else if (state.transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.AccountTotalLiabilities.type) {
if (!account.isLiability) {
continue;
}
}
if (state.transactionStatisticsFilter.filterAccountIds && state.transactionStatisticsFilter.filterAccountIds[account.id]) {
continue;
}
let primaryAccount = accountsStore.allAccountsMap[account.parentId];
if (!primaryAccount) {
primaryAccount = account;
}
let amount = account.balance;
if (account.currency !== userStore.currentUserDefaultCurrency) {
amount = Math.floor(exchangeRatesStore.getExchangedAmount(amount, account.currency, userStore.currentUserDefaultCurrency));
if (!isNumber(amount)) {
continue;
}
}
if (account.isLiability) {
amount = -amount;
}
const data = {
name: account.name,
type: 'account',
id: account.id,
icon: account.icon || iconConstants.defaultAccountIcon.icon,
color: account.color || colorConstants.defaultAccountColor,
hidden: primaryAccount.hidden || account.hidden,
displayOrders: [primaryAccount.category, primaryAccount.displayOrder, account.displayOrder],
totalAmount: amount
};
totalAmount += amount;
if (amount > 0) {
totalNonNegativeAmount += amount;
}
allDataItems[account.id] = data;
}
return {
totalAmount: totalAmount,
totalNonNegativeAmount: totalNonNegativeAmount,
items: allDataItems
}
},
categoricalAnalysisData(state) {
let combinedData = {
items: [],
totalAmount: 0
};
if (state.transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.ExpenseByAccount.type ||
state.transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.ExpenseByPrimaryCategory.type ||
state.transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.ExpenseBySecondaryCategory.type ||
state.transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.IncomeByAccount.type ||
state.transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.IncomeByPrimaryCategory.type ||
state.transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.IncomeBySecondaryCategory.type) {
combinedData = state.transactionCategoryTotalAmountAnalysisData;
} else if (state.transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.AccountTotalAssets.type ||
state.transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.AccountTotalLiabilities.type) {
combinedData = state.accountTotalAmountAnalysisData;
}
const allStatisticsItems = [];
for (let id in combinedData.items) {
if (!Object.prototype.hasOwnProperty.call(combinedData.items, id)) {
continue;
}
const data = combinedData.items[id];
if (data.totalAmount > 0) {
data.percent = data.totalAmount * 100 / combinedData.totalNonNegativeAmount;
} else {
data.percent = 0;
}
if (data.percent < 0) {
data.percent = 0;
}
allStatisticsItems.push(data);
}
sortCategoryTotalAmountItems(allStatisticsItems, state.transactionStatisticsFilter);
return {
totalAmount: combinedData.totalAmount,
items: allStatisticsItems
};
},
transactionCategoryTrendsDataWithCategoryAndAccountInfo(state) {
const trendsData = state.transactionCategoryTrendsData;
const finalTrendsData = [];
if (trendsData && trendsData.length) {
const userStore = useUserStore();
const accountsStore = useAccountsStore();
const transactionCategoriesStore = useTransactionCategoriesStore();
const exchangeRatesStore = useExchangeRatesStore();
for (let i = 0; i < trendsData.length; i++) {
const trendItem = trendsData[i];
const finalTrendItem = {
year: trendItem.year,
month: trendItem.month,
items: []
};
if (trendItem && trendItem.items && trendItem.items.length) {
finalTrendItem.items = assembleAccountAndCategoryInfo(userStore, accountsStore, transactionCategoriesStore, exchangeRatesStore, trendItem.items);
}
finalTrendsData.push(finalTrendItem);
}
}
return finalTrendsData;
},
trendsAnalysisData(state) {
if (!state.transactionCategoryTrendsDataWithCategoryAndAccountInfo || !state.transactionCategoryTrendsDataWithCategoryAndAccountInfo.length) {
return null;
}
const combinedDataMap = {};
for (let i = 0; i < state.transactionCategoryTrendsDataWithCategoryAndAccountInfo.length; i++) {
const trendItem = state.transactionCategoryTrendsDataWithCategoryAndAccountInfo[i];
const totalAmountItems = getCategoryTotalAmountItems(trendItem.items, state.transactionStatisticsFilter);
for (let id in totalAmountItems.items) {
if (!Object.prototype.hasOwnProperty.call(totalAmountItems.items, id)) {
continue;
}
const item = totalAmountItems.items[id];
let combinedData = combinedDataMap[id];
if (!combinedData) {
combinedData = {
name: item.name,
type: item.type,
id: item.id,
icon: item.icon,
color: item.color,
hidden: item.hidden,
displayOrders: item.displayOrders,
totalAmount: 0,
items: []
};
}
combinedData.items.push({
year: trendItem.year,
month: trendItem.month,
totalAmount: item.totalAmount
});
combinedData.totalAmount += item.totalAmount;
combinedDataMap[id] = combinedData;
}
}
const totalAmountsTrends = [];
for (let id in combinedDataMap) {
if (!Object.prototype.hasOwnProperty.call(combinedDataMap, id)) {
continue;
}
const trendData = combinedDataMap[id];
totalAmountsTrends.push(trendData);
}
sortCategoryTotalAmountItems(totalAmountsTrends, state.transactionStatisticsFilter);
return {
items: totalAmountsTrends
};
}
},
actions: {
updateTransactionStatisticsInvalidState(invalidState) {
this.transactionStatisticsStateInvalid = invalidState;
},
resetTransactionStatistics() {
this.transactionStatisticsFilter.chartDataType = statisticsConstants.defaultChartDataType;
this.transactionStatisticsFilter.categoricalChartType = statisticsConstants.defaultCategoricalChartType;
this.transactionStatisticsFilter.categoricalChartDateType = statisticsConstants.defaultCategoricalChartDataRangeType;
this.transactionStatisticsFilter.categoricalChartStartTime = 0;
this.transactionStatisticsFilter.categoricalChartEndTime = 0;
this.transactionStatisticsFilter.trendChartType = statisticsConstants.defaultTrendChartType;
this.transactionStatisticsFilter.trendChartDateType = statisticsConstants.defaultTrendChartDataRangeType;
this.transactionStatisticsFilter.trendChartStartYearMonth = '';
this.transactionStatisticsFilter.trendChartEndYearMonth = '';
this.transactionStatisticsFilter.filterAccountIds = {};
this.transactionStatisticsFilter.filterCategoryIds = {};
this.transactionCategoryStatisticsData = {};
this.transactionCategoryTrendsData = {};
this.transactionStatisticsStateInvalid = true;
},
initTransactionStatisticsFilter(analysisType, filter) {
const settingsStore = useSettingsStore();
const userStore = useUserStore();
if (filter && isInteger(filter.chartDataType)) {
this.transactionStatisticsFilter.chartDataType = filter.chartDataType;
} else {
this.transactionStatisticsFilter.chartDataType = settingsStore.appSettings.statistics.defaultChartDataType;
}
if (analysisType === statisticsConstants.allAnalysisTypes.CategoricalAnalysis || analysisType === statisticsConstants.allAnalysisTypes.TrendAnalysis) {
if (!statisticsConstants.allChartDataTypesMap[this.transactionStatisticsFilter.chartDataType] ||
!statisticsConstants.allChartDataTypesMap[this.transactionStatisticsFilter.chartDataType].availableAnalysisTypes[analysisType]) {
this.transactionStatisticsFilter.chartDataType = statisticsConstants.defaultChartDataType;
}
}
if (filter && isInteger(filter.categoricalChartType)) {
this.transactionStatisticsFilter.categoricalChartType = filter.categoricalChartType;
} else {
this.transactionStatisticsFilter.categoricalChartType = settingsStore.appSettings.statistics.defaultCategoricalChartType;
}
if (this.transactionStatisticsFilter.categoricalChartType !== statisticsConstants.allCategoricalChartTypes.Pie && this.transactionStatisticsFilter.categoricalChartType !== statisticsConstants.allCategoricalChartTypes.Bar) {
this.transactionStatisticsFilter.categoricalChartType = statisticsConstants.defaultCategoricalChartType;
}
if (filter && isInteger(filter.categoricalChartDateType)) {
this.transactionStatisticsFilter.categoricalChartDateType = filter.categoricalChartDateType;
} else {
this.transactionStatisticsFilter.categoricalChartDateType = settingsStore.appSettings.statistics.defaultCategoricalChartDataRangeType;
}
let categoricalChartDateTypeValid = true;
if (!datetimeConstants.allDateRangesMap[this.transactionStatisticsFilter.categoricalChartDateType] ||
!datetimeConstants.allDateRangesMap[this.transactionStatisticsFilter.categoricalChartDateType].availableScenes[datetimeConstants.allDateRangeScenes.Normal]) {
this.transactionStatisticsFilter.categoricalChartDateType = statisticsConstants.defaultCategoricalChartDataRangeType;
categoricalChartDateTypeValid = false;
}
if (categoricalChartDateTypeValid && this.transactionStatisticsFilter.categoricalChartDateType === datetimeConstants.allDateRanges.Custom.type) {
if (filter && isInteger(filter.categoricalChartStartTime)) {
this.transactionStatisticsFilter.categoricalChartStartTime = filter.categoricalChartStartTime;
} else {
this.transactionStatisticsFilter.categoricalChartStartTime = 0;
}
if (filter && isInteger(filter.categoricalChartEndTime)) {
this.transactionStatisticsFilter.categoricalChartEndTime = filter.categoricalChartEndTime;
} else {
this.transactionStatisticsFilter.categoricalChartEndTime = 0;
}
} else {
const categoricalChartDateRange = getDateRangeByDateType(this.transactionStatisticsFilter.categoricalChartDateType, userStore.currentUserFirstDayOfWeek);
this.transactionStatisticsFilter.categoricalChartDateType = categoricalChartDateRange.dateType;
this.transactionStatisticsFilter.categoricalChartStartTime = categoricalChartDateRange.minTime;
this.transactionStatisticsFilter.categoricalChartEndTime = categoricalChartDateRange.maxTime;
}
if (filter && isInteger(filter.trendChartType)) {
this.transactionStatisticsFilter.trendChartType = filter.trendChartType;
} else {
this.transactionStatisticsFilter.trendChartType = settingsStore.appSettings.statistics.defaultTrendChartType;
}
if (this.transactionStatisticsFilter.trendChartType !== statisticsConstants.allTrendChartTypes.Area && this.transactionStatisticsFilter.trendChartType !== statisticsConstants.allTrendChartTypes.Column) {
this.transactionStatisticsFilter.trendChartType = statisticsConstants.defaultTrendChartType;
}
if (filter && isInteger(filter.trendChartDateType)) {
this.transactionStatisticsFilter.trendChartDateType = filter.trendChartDateType;
} else {
this.transactionStatisticsFilter.trendChartDateType = settingsStore.appSettings.statistics.defaultTrendChartDataRangeType;
}
let trendChartDateTypeValid = true;
if (!datetimeConstants.allDateRangesMap[this.transactionStatisticsFilter.trendChartDateType] ||
!datetimeConstants.allDateRangesMap[this.transactionStatisticsFilter.trendChartDateType].availableScenes[datetimeConstants.allDateRangeScenes.TrendAnalysis]) {
this.transactionStatisticsFilter.trendChartDateType = statisticsConstants.defaultTrendChartDataRangeType;
trendChartDateTypeValid = false;
}
if (trendChartDateTypeValid && this.transactionStatisticsFilter.trendChartDateType === datetimeConstants.allDateRanges.Custom.type) {
if (filter && isYearMonth(filter.trendChartStartYearMonth)) {
this.transactionStatisticsFilter.trendChartStartYearMonth = filter.trendChartStartYearMonth;
} else {
this.transactionStatisticsFilter.trendChartStartYearMonth = '';
}
if (filter && isYearMonth(filter.trendChartEndYearMonth)) {
this.transactionStatisticsFilter.trendChartEndYearMonth = filter.trendChartEndYearMonth;
} else {
this.transactionStatisticsFilter.trendChartEndYearMonth = '';
}
} else {
const trendChartDateRange = getDateRangeByDateType(this.transactionStatisticsFilter.trendChartDateType, userStore.currentUserFirstDayOfWeek);
this.transactionStatisticsFilter.trendChartDateType = trendChartDateRange.dateType;
this.transactionStatisticsFilter.trendChartStartYearMonth = getYearAndMonthFromUnixTime(trendChartDateRange.minTime);
this.transactionStatisticsFilter.trendChartEndYearMonth = getYearAndMonthFromUnixTime(trendChartDateRange.maxTime);
}
if (filter && isObject(filter.filterAccountIds)) {
this.transactionStatisticsFilter.filterAccountIds = filter.filterAccountIds;
} else {
this.transactionStatisticsFilter.filterAccountIds = settingsStore.appSettings.statistics.defaultAccountFilter || {};
}
if (filter && isObject(filter.filterCategoryIds)) {
this.transactionStatisticsFilter.filterCategoryIds = filter.filterCategoryIds;
} else {
this.transactionStatisticsFilter.filterCategoryIds = settingsStore.appSettings.statistics.defaultTransactionCategoryFilter || {};
}
if (filter && isInteger(filter.sortingType)) {
this.transactionStatisticsFilter.sortingType = filter.sortingType;
} else {
this.transactionStatisticsFilter.sortingType = settingsStore.appSettings.statistics.defaultSortingType;
}
if (this.transactionStatisticsFilter.sortingType < statisticsConstants.allSortingTypes.Amount.type || this.transactionStatisticsFilter.sortingType > statisticsConstants.allSortingTypes.Name.type) {
this.transactionStatisticsFilter.sortingType = statisticsConstants.defaultSortingType;
}
},
updateTransactionStatisticsFilter(filter) {
let changed = false;
if (filter && isInteger(filter.chartDataType) && this.transactionStatisticsFilter.chartDataType !== filter.chartDataType) {
this.transactionStatisticsFilter.chartDataType = filter.chartDataType;
changed = true;
}
if (filter && isInteger(filter.categoricalChartType) && this.transactionStatisticsFilter.categoricalChartType !== filter.categoricalChartType) {
this.transactionStatisticsFilter.categoricalChartType = filter.categoricalChartType;
changed = true;
}
if (filter && isInteger(filter.categoricalChartDateType) && this.transactionStatisticsFilter.categoricalChartDateType !== filter.categoricalChartDateType) {
this.transactionStatisticsFilter.categoricalChartDateType = filter.categoricalChartDateType;
changed = true;
}
if (filter && isInteger(filter.categoricalChartStartTime) && this.transactionStatisticsFilter.categoricalChartStartTime !== filter.categoricalChartStartTime) {
this.transactionStatisticsFilter.categoricalChartStartTime = filter.categoricalChartStartTime;
changed = true;
}
if (filter && isInteger(filter.categoricalChartEndTime) && this.transactionStatisticsFilter.categoricalChartEndTime !== filter.categoricalChartEndTime) {
this.transactionStatisticsFilter.categoricalChartEndTime = filter.categoricalChartEndTime;
changed = true;
}
if (filter && isInteger(filter.trendChartType) && this.transactionStatisticsFilter.trendChartType !== filter.trendChartType) {
this.transactionStatisticsFilter.trendChartType = filter.trendChartType;
changed = true;
}
if (filter && isInteger(filter.trendChartDateType) && this.transactionStatisticsFilter.trendChartDateType !== filter.trendChartDateType) {
this.transactionStatisticsFilter.trendChartDateType = filter.trendChartDateType;
changed = true;
}
if (filter && (isYearMonth(filter.trendChartStartYearMonth) || filter.trendChartStartYearMonth === '') && !isYearMonthEquals(this.transactionStatisticsFilter.trendChartStartYearMonth, filter.trendChartStartYearMonth)) {
this.transactionStatisticsFilter.trendChartStartYearMonth = filter.trendChartStartYearMonth;
changed = true;
}
if (filter && (isYearMonth(filter.trendChartEndYearMonth) || filter.trendChartEndYearMonth === '') && !isYearMonthEquals(this.transactionStatisticsFilter.trendChartEndYearMonth, filter.trendChartEndYearMonth)) {
this.transactionStatisticsFilter.trendChartEndYearMonth = filter.trendChartEndYearMonth;
changed = true;
}
if (filter && isObject(filter.filterAccountIds) && !isEquals(this.transactionStatisticsFilter.filterAccountIds, filter.filterAccountIds)) {
this.transactionStatisticsFilter.filterAccountIds = filter.filterAccountIds;
changed = true;
}
if (filter && isObject(filter.filterCategoryIds) && !isEquals(this.transactionStatisticsFilter.filterCategoryIds, filter.filterCategoryIds)) {
this.transactionStatisticsFilter.filterCategoryIds = filter.filterCategoryIds;
changed = true;
}
if (filter && isInteger(filter.sortingType) && this.transactionStatisticsFilter.sortingType !== filter.sortingType) {
this.transactionStatisticsFilter.sortingType = filter.sortingType;
changed = true;
}
return changed;
},
getTransactionStatisticsPageParams(analysisType, trendDateAggregationType) {
const querys = [];
querys.push('analysisType=' + analysisType);
querys.push('chartDataType=' + this.transactionStatisticsFilter.chartDataType);
if (analysisType === statisticsConstants.allAnalysisTypes.CategoricalAnalysis) {
querys.push('chartType=' + this.transactionStatisticsFilter.categoricalChartType);
querys.push('chartDateType=' + this.transactionStatisticsFilter.categoricalChartDateType);
if (this.transactionStatisticsFilter.categoricalChartDateType === datetimeConstants.allDateRanges.Custom.type) {
querys.push('startTime=' + this.transactionStatisticsFilter.categoricalChartStartTime);
querys.push('endTime=' + this.transactionStatisticsFilter.categoricalChartEndTime);
}
} else if (analysisType === statisticsConstants.allAnalysisTypes.TrendAnalysis) {
querys.push('chartType=' + this.transactionStatisticsFilter.trendChartType);
querys.push('chartDateType=' + this.transactionStatisticsFilter.trendChartDateType);
if (this.transactionStatisticsFilter.trendChartDateType === datetimeConstants.allDateRanges.Custom.type) {
querys.push('startTime=' + this.transactionStatisticsFilter.trendChartStartYearMonth);
querys.push('endTime=' + this.transactionStatisticsFilter.trendChartEndYearMonth);
}
if (trendDateAggregationType !== statisticsConstants.allDateAggregationTypes.Month.type) {
querys.push('trendDateAggregationType=' + trendDateAggregationType);
}
}
if (this.transactionStatisticsFilter.filterAccountIds) {
const ids = objectFieldToArrayItem(this.transactionStatisticsFilter.filterAccountIds);
if (ids && ids.length) {
querys.push('filterAccountIds=' + ids.join(','));
}
}
if (this.transactionStatisticsFilter.filterCategoryIds) {
const ids = objectFieldToArrayItem(this.transactionStatisticsFilter.filterCategoryIds);
if (ids && ids.length) {
querys.push('filterCategoryIds=' + ids.join(','));
}
}
querys.push('sortingType=' + this.transactionStatisticsFilter.sortingType);
return querys.join('&');
},
getTransactionListPageParams(analysisType, itemId, dateRange) {
const accountsStore = useAccountsStore();
const transactionCategoriesStore = useTransactionCategoriesStore();
const querys = [];
if (this.transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.IncomeByAccount.type
|| this.transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.IncomeByPrimaryCategory.type
|| this.transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.IncomeBySecondaryCategory.type
|| this.transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.TotalIncome.type) {
querys.push('type=2');
} else if (this.transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.ExpenseByAccount.type
|| this.transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.ExpenseByPrimaryCategory.type
|| this.transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.ExpenseBySecondaryCategory.type
|| this.transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.TotalExpense.type) {
querys.push('type=3');
}
if (this.transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.IncomeByAccount.type
|| this.transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.ExpenseByAccount.type
|| this.transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.AccountTotalAssets.type
|| this.transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.AccountTotalLiabilities.type) {
querys.push('accountIds=' + itemId);
if (!isObjectEmpty(this.transactionStatisticsFilter.filterCategoryIds)) {
querys.push('categoryIds=' + getFinalCategoryIdsByFilteredCategoryIds(transactionCategoriesStore.allTransactionCategoriesMap, this.transactionStatisticsFilter.filterCategoryIds));
}
} else if (this.transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.IncomeByPrimaryCategory.type
|| this.transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.IncomeBySecondaryCategory.type
|| this.transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.ExpenseByPrimaryCategory.type
|| this.transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.ExpenseBySecondaryCategory.type) {
querys.push('categoryIds=' + itemId);
if (!isObjectEmpty(this.transactionStatisticsFilter.filterAccountIds)) {
querys.push('accountIds=' + getFinalAccountIdsByFilteredAccountIds(accountsStore.allAccountsMap, this.transactionStatisticsFilter.filterAccountIds));
}
}
if (analysisType === statisticsConstants.allAnalysisTypes.CategoricalAnalysis
&& this.transactionStatisticsFilter.chartDataType !== statisticsConstants.allChartDataTypes.AccountTotalAssets.type
&& this.transactionStatisticsFilter.chartDataType !== statisticsConstants.allChartDataTypes.AccountTotalLiabilities.type) {
querys.push('dateType=' + this.transactionStatisticsFilter.categoricalChartDateType);
if (this.transactionStatisticsFilter.categoricalChartDateType === datetimeConstants.allDateRanges.Custom.type) {
querys.push('minTime=' + this.transactionStatisticsFilter.categoricalChartStartTime);
querys.push('maxTime=' + this.transactionStatisticsFilter.categoricalChartEndTime);
}
} else if (analysisType === statisticsConstants.allAnalysisTypes.TrendAnalysis && dateRange) {
querys.push('dateType=' + dateRange.type);
querys.push('minTime=' + dateRange.minTime);
querys.push('maxTime=' + dateRange.maxTime);
}
return querys.join('&');
},
loadCategoricalAnalysis({ force }) {
const self = this;
const settingsStore = useSettingsStore();
return new Promise((resolve, reject) => {
services.getTransactionStatistics({
startTime: self.transactionStatisticsFilter.categoricalChartStartTime,
endTime: self.transactionStatisticsFilter.categoricalChartEndTime,
useTransactionTimezone: settingsStore.appSettings.statistics.defaultTimezoneType
}).then(response => {
const data = response.data;
if (!data || !data.success || !data.result) {
reject({ message: 'Unable to retrieve transaction statistics' });
return;
}
if (self.transactionStatisticsStateInvalid) {
self.updateTransactionStatisticsInvalidState(false);
}
if (force && data.result && isEquals(self.transactionCategoryStatisticsData, data.result)) {
reject({ message: 'Data is up to date' });
return;
}
self.transactionCategoryStatisticsData = data.result;
resolve(data.result);
}).catch(error => {
logger.error('failed to retrieve transaction statistics', error);
if (error.response && error.response.data && error.response.data.errorMessage) {
reject({ error: error.response.data });
} else if (!error.processed) {
reject({ message: 'Unable to retrieve transaction statistics' });
} else {
reject(error);
}
});
});
},
loadTrendAnalysis({ force }) {
const self = this;
const settingsStore = useSettingsStore();
return new Promise((resolve, reject) => {
services.getTransactionStatisticsTrends({
startYearMonth: self.transactionStatisticsFilter.trendChartStartYearMonth,
endYearMonth: self.transactionStatisticsFilter.trendChartEndYearMonth,
useTransactionTimezone: settingsStore.appSettings.statistics.defaultTimezoneType
}).then(response => {
const data = response.data;
if (!data || !data.success || !data.result) {
reject({ message: 'Unable to retrieve transaction statistics' });
return;
}
if (self.transactionStatisticsStateInvalid) {
self.updateTransactionStatisticsInvalidState(false);
}
if (force && data.result && isEquals(self.transactionCategoryTrendsData, data.result)) {
reject({ message: 'Data is up to date' });
return;
}
self.transactionCategoryTrendsData = data.result;
resolve(data.result);
}).catch(error => {
logger.error('failed to retrieve transaction statistics', error);
if (error.response && error.response.data && error.response.data.errorMessage) {
reject({ error: error.response.data });
} else if (!error.processed) {
reject({ message: 'Unable to retrieve transaction statistics' });
} else {
reject(error);
}
});
});
},
}
});