add outflows / inflows / net cash flow in statistics & analysis

This commit is contained in:
MaysWind
2025-10-27 00:52:41 +08:00
parent 9a2f682379
commit 5cb7eca340
26 changed files with 226 additions and 49 deletions
@@ -190,7 +190,11 @@ export function useStatisticsTransactionPageBase() {
});
const totalAmountName = computed<string>(() => {
if (query.value.chartDataType === ChartDataType.IncomeByAccount.type
if (query.value.chartDataType === ChartDataType.InflowsByAccount.type) {
return tt('Total Inflows');
} else if (query.value.chartDataType === ChartDataType.OutflowsByAccount.type) {
return tt('Total Outflows');
} else if (query.value.chartDataType === ChartDataType.IncomeByAccount.type
|| query.value.chartDataType === ChartDataType.IncomeByPrimaryCategory.type
|| query.value.chartDataType === ChartDataType.IncomeBySecondaryCategory.type) {
return tt('Total Income');
@@ -208,15 +212,21 @@ export function useStatisticsTransactionPageBase() {
});
const showTotalAmountInTrendsChart = computed<boolean>(() => {
return query.value.chartDataType !== ChartDataType.TotalExpense.type &&
return query.value.chartDataType !== ChartDataType.TotalOutflows.type &&
query.value.chartDataType !== ChartDataType.TotalExpense.type &&
query.value.chartDataType !== ChartDataType.TotalInflows.type &&
query.value.chartDataType !== ChartDataType.TotalIncome.type &&
query.value.chartDataType !== ChartDataType.TotalBalance.type;
query.value.chartDataType !== ChartDataType.NetCashFlow.type &&
query.value.chartDataType !== ChartDataType.NetIncome.type;
});
const translateNameInTrendsChart = computed<boolean>(() => {
return query.value.chartDataType === ChartDataType.TotalExpense.type ||
return query.value.chartDataType === ChartDataType.TotalOutflows.type ||
query.value.chartDataType === ChartDataType.TotalExpense.type ||
query.value.chartDataType === ChartDataType.TotalInflows.type ||
query.value.chartDataType === ChartDataType.TotalIncome.type ||
query.value.chartDataType === ChartDataType.TotalBalance.type;
query.value.chartDataType === ChartDataType.NetCashFlow.type ||
query.value.chartDataType === ChartDataType.NetIncome.type;
});
const categoricalAnalysisData = computed<TransactionCategoricalAnalysisData>(() => statisticsStore.categoricalAnalysisData);
@@ -48,7 +48,7 @@
<v-main>
<v-window class="d-flex flex-grow-1 disable-tab-transition w-100-window-container" v-model="activeTab">
<v-window-item value="statisticsPage">
<v-card variant="flat" min-height="680">
<v-card variant="flat" :min-height="queryAnalysisType === StatisticsAnalysisType.TrendAnalysis ? '860' : '700'">
<template #title>
<div class="title-and-toolbar d-flex align-center">
<v-btn class="me-3 d-md-none" density="compact" color="default" variant="plain"
@@ -577,11 +577,13 @@ const querySortingType = computed<number>({
});
const statisticsTextColor = computed<string>(() => {
if (query.value.chartDataType === ChartDataType.ExpenseByAccount.type ||
if (query.value.chartDataType === ChartDataType.OutflowsByAccount.type ||
query.value.chartDataType === ChartDataType.ExpenseByAccount.type ||
query.value.chartDataType === ChartDataType.ExpenseByPrimaryCategory.type ||
query.value.chartDataType === ChartDataType.ExpenseBySecondaryCategory.type) {
return 'text-expense';
} else if (query.value.chartDataType === ChartDataType.IncomeByAccount.type ||
} else if (query.value.chartDataType === ChartDataType.InflowsByAccount.type ||
query.value.chartDataType === ChartDataType.IncomeByAccount.type ||
query.value.chartDataType === ChartDataType.IncomeByPrimaryCategory.type ||
query.value.chartDataType === ChartDataType.IncomeBySecondaryCategory.type) {
return 'text-income';
@@ -703,15 +705,20 @@ function reload(force: boolean): Promise<unknown> | null {
loading.value = true;
if (query.value.chartDataType === ChartDataType.ExpenseByAccount.type ||
if (query.value.chartDataType === ChartDataType.OutflowsByAccount.type ||
query.value.chartDataType === ChartDataType.ExpenseByAccount.type ||
query.value.chartDataType === ChartDataType.ExpenseByPrimaryCategory.type ||
query.value.chartDataType === ChartDataType.ExpenseBySecondaryCategory.type ||
query.value.chartDataType === ChartDataType.InflowsByAccount.type ||
query.value.chartDataType === ChartDataType.IncomeByAccount.type ||
query.value.chartDataType === ChartDataType.IncomeByPrimaryCategory.type ||
query.value.chartDataType === ChartDataType.IncomeBySecondaryCategory.type ||
query.value.chartDataType === ChartDataType.TotalOutflows.type ||
query.value.chartDataType === ChartDataType.TotalExpense.type ||
query.value.chartDataType === ChartDataType.TotalInflows.type ||
query.value.chartDataType === ChartDataType.TotalIncome.type ||
query.value.chartDataType === ChartDataType.TotalBalance.type) {
query.value.chartDataType === ChartDataType.NetCashFlow.type ||
query.value.chartDataType === ChartDataType.NetIncome.type) {
if (analysisType.value === StatisticsAnalysisType.CategoricalAnalysis) {
dispatchPromise = statisticsStore.loadCategoricalAnalysis({
force: force
@@ -109,7 +109,7 @@
</div>
</div>
<div class="display-flex full-line">
<div :class="{ 'statistics-list-item-overview-amount': true, 'text-expense': query.chartDataType === ChartDataType.ExpenseByAccount.type || query.chartDataType === ChartDataType.ExpenseByPrimaryCategory.type || query.chartDataType === ChartDataType.ExpenseBySecondaryCategory.type, 'text-income': query.chartDataType === ChartDataType.IncomeByAccount.type || query.chartDataType === ChartDataType.IncomeByPrimaryCategory.type || query.chartDataType === ChartDataType.IncomeBySecondaryCategory.type }">
<div :class="{ 'statistics-list-item-overview-amount': true, 'text-expense': query.chartDataType === ChartDataType.OutflowsByAccount.type || query.chartDataType === ChartDataType.ExpenseByAccount.type || query.chartDataType === ChartDataType.ExpenseByPrimaryCategory.type || query.chartDataType === ChartDataType.ExpenseBySecondaryCategory.type, 'text-income': query.chartDataType === ChartDataType.InflowsByAccount.type || query.chartDataType === ChartDataType.IncomeByAccount.type || query.chartDataType === ChartDataType.IncomeByPrimaryCategory.type || query.chartDataType === ChartDataType.IncomeBySecondaryCategory.type }">
<span v-if="!loading && categoricalAnalysisData && categoricalAnalysisData.items && categoricalAnalysisData.items.length">
{{ getDisplayAmount(categoricalAnalysisData.totalAmount, defaultCurrency) }}
</span>
@@ -490,15 +490,20 @@ function reload(done?: () => void): void {
reloading.value = true;
if (query.value.chartDataType === ChartDataType.ExpenseByAccount.type ||
if (query.value.chartDataType === ChartDataType.OutflowsByAccount.type ||
query.value.chartDataType === ChartDataType.ExpenseByAccount.type ||
query.value.chartDataType === ChartDataType.ExpenseByPrimaryCategory.type ||
query.value.chartDataType === ChartDataType.ExpenseBySecondaryCategory.type ||
query.value.chartDataType === ChartDataType.InflowsByAccount.type ||
query.value.chartDataType === ChartDataType.IncomeByAccount.type ||
query.value.chartDataType === ChartDataType.IncomeByPrimaryCategory.type ||
query.value.chartDataType === ChartDataType.IncomeBySecondaryCategory.type ||
query.value.chartDataType === ChartDataType.TotalOutflows.type ||
query.value.chartDataType === ChartDataType.TotalExpense.type ||
query.value.chartDataType === ChartDataType.TotalInflows.type ||
query.value.chartDataType === ChartDataType.TotalIncome.type ||
query.value.chartDataType === ChartDataType.TotalBalance.type) {
query.value.chartDataType === ChartDataType.NetCashFlow.type ||
query.value.chartDataType === ChartDataType.NetIncome.type) {
if (analysisType.value === StatisticsAnalysisType.CategoricalAnalysis) {
dispatchPromise = statisticsStore.loadCategoricalAnalysis({
force: force