From d0f76fea22588e21a11258a7b2de14011ceb937b Mon Sep 17 00:00:00 2001 From: MaysWind Date: Tue, 12 May 2026 00:21:02 +0800 Subject: [PATCH] support configuring the default behavior of the reconciliation statement button and the default time range for the reconciliation statement page --- pkg/models/user_app_cloud_setting.go | 8 +++-- src/core/setting.ts | 10 +++++- src/core/statistics.ts | 3 ++ src/locales/de.json | 2 ++ src/locales/en.json | 2 ++ src/locales/es.json | 2 ++ src/locales/fr.json | 2 ++ src/locales/it.json | 2 ++ src/locales/ja.json | 2 ++ src/locales/kn.json | 2 ++ src/locales/ko.json | 2 ++ src/locales/nl.json | 2 ++ src/locales/pt_BR.json | 2 ++ src/locales/ru.json | 2 ++ src/locales/sl.json | 2 ++ src/locales/ta.json | 2 ++ src/locales/th.json | 2 ++ src/locales/tr.json | 2 ++ src/locales/uk.json | 2 ++ src/locales/vi.json | 2 ++ src/locales/zh_Hans.json | 2 ++ src/locales/zh_Hant.json | 2 ++ src/stores/setting.ts | 14 ++++++++ .../base/settings/AppCloudSyncPageBase.ts | 4 ++- .../base/settings/AppSettingsPageBase.ts | 30 ++++++++++++++-- .../transactions/TransactionListPageBase.ts | 2 +- src/views/desktop/accounts/ListPage.vue | 25 ++++++++++--- .../app/settings/tabs/AppBasicSettingTab.vue | 21 ++++++++++- .../accounts/ReconciliationStatementPage.vue | 32 +++++++++++++++-- .../mobile/settings/PageSettingsPage.vue | 36 ++++++++++++++++++- 30 files changed, 206 insertions(+), 17 deletions(-) diff --git a/pkg/models/user_app_cloud_setting.go b/pkg/models/user_app_cloud_setting.go index 6214a6c0..d9df1798 100644 --- a/pkg/models/user_app_cloud_setting.go +++ b/pkg/models/user_app_cloud_setting.go @@ -41,9 +41,11 @@ var ALL_ALLOWED_CLOUD_SYNC_APP_SETTING_KEY_TYPES = map[string]UserApplicationClo "insightsExplorerDefaultDateRangeType": USER_APPLICATION_CLOUD_SETTING_TYPE_NUMBER, "showTagInInsightsExplorerPage": USER_APPLICATION_CLOUD_SETTING_TYPE_BOOLEAN, // Account List Page - "totalAmountExcludeAccountIds": USER_APPLICATION_CLOUD_SETTING_TYPE_STRING_BOOLEAN_MAP, - "accountCategoryOrders": USER_APPLICATION_CLOUD_SETTING_TYPE_STRING, - "hideCategoriesWithoutAccounts": USER_APPLICATION_CLOUD_SETTING_TYPE_BOOLEAN, + "totalAmountExcludeAccountIds": USER_APPLICATION_CLOUD_SETTING_TYPE_STRING_BOOLEAN_MAP, + "accountCategoryOrders": USER_APPLICATION_CLOUD_SETTING_TYPE_STRING, + "hideCategoriesWithoutAccounts": USER_APPLICATION_CLOUD_SETTING_TYPE_BOOLEAN, + "reconciliationStatementButtonDefaultDateRangeTypeInDesktop": USER_APPLICATION_CLOUD_SETTING_TYPE_NUMBER, + "reconciliationStatementPageDefaultDateRangeTypeInMobile": USER_APPLICATION_CLOUD_SETTING_TYPE_NUMBER, // Exchange Rates Data Page "currencySortByInExchangeRatesPage": USER_APPLICATION_CLOUD_SETTING_TYPE_NUMBER, // Browser Cache Management diff --git a/src/core/setting.ts b/src/core/setting.ts index 03645dbe..4f644aea 100644 --- a/src/core/setting.ts +++ b/src/core/setting.ts @@ -12,7 +12,9 @@ import { ChartSortingType, DEFAULT_CATEGORICAL_CHART_DATA_RANGE, DEFAULT_TREND_CHART_DATA_RANGE, - DEFAULT_ASSET_TRENDS_CHART_DATA_RANGE + DEFAULT_ASSET_TRENDS_CHART_DATA_RANGE, + DEFAULT_RECONCILIATION_STATEMENT_DATE_RANGE_IN_DESKTOP, + DEFAULT_RECONCILIATION_STATEMENT_DATE_RANGE_IN_MOBILE, } from './statistics.ts'; import { DEFAULT_TRANSACTION_EXPLORER_DATE_RANGE } from './explorer.ts'; import { DEFAULT_CURRENCY_CODE } from '@/consts/currency.ts'; @@ -66,6 +68,8 @@ export interface ApplicationSettings extends BaseApplicationSetting { totalAmountExcludeAccountIds: Record; accountCategoryOrders: string; hideCategoriesWithoutAccounts: boolean; + reconciliationStatementButtonDefaultDateRangeTypeInDesktop: number; + reconciliationStatementPageDefaultDateRangeTypeInMobile: number; // Exchange Rates Data Page currencySortByInExchangeRatesPage: number; // Browser Cache Management @@ -144,6 +148,8 @@ export const ALL_ALLOWED_CLOUD_SYNC_APP_SETTING_KEY_TYPES: Record { updateUserApplicationCloudSettingValue('hideCategoriesWithoutAccounts', value); } + function setReconciliationStatementButtonDefaultDateRangeTypeInDesktop(value: number): void { + updateApplicationSettingsValue('reconciliationStatementButtonDefaultDateRangeTypeInDesktop', value); + appSettings.value.reconciliationStatementButtonDefaultDateRangeTypeInDesktop = value; + updateUserApplicationCloudSettingValue('reconciliationStatementButtonDefaultDateRangeTypeInDesktop', value); + } + + function setReconciliationStatementPageDefaultDateRangeTypeInMobile(value: number): void { + updateApplicationSettingsValue('reconciliationStatementPageDefaultDateRangeTypeInMobile', value); + appSettings.value.reconciliationStatementPageDefaultDateRangeTypeInMobile = value; + updateUserApplicationCloudSettingValue('reconciliationStatementPageDefaultDateRangeTypeInMobile', value); + } + // Exchange Rates Data Page function setCurrencySortByInExchangeRatesPage(value: number): void { updateApplicationSettingsValue('currencySortByInExchangeRatesPage', value); @@ -558,6 +570,8 @@ export const useSettingsStore = defineStore('settings', () => { setTotalAmountExcludeAccountIds, setAccountCategoryOrders, setHideCategoriesWithoutAccounts, + setReconciliationStatementButtonDefaultDateRangeTypeInDesktop, + setReconciliationStatementPageDefaultDateRangeTypeInMobile, // -- Exchange Rates Data Page setCurrencySortByInExchangeRatesPage, // -- Browser Cache Management diff --git a/src/views/base/settings/AppCloudSyncPageBase.ts b/src/views/base/settings/AppCloudSyncPageBase.ts index fa378f68..131f31fb 100644 --- a/src/views/base/settings/AppCloudSyncPageBase.ts +++ b/src/views/base/settings/AppCloudSyncPageBase.ts @@ -78,7 +78,9 @@ export const ALL_APPLICATION_CLOUD_SETTINGS: CategorizedApplicationCloudSettingI items: [ { settingKey: 'totalAmountExcludeAccountIds', settingName: 'Accounts Included in Total', mobile: true, desktop: true }, { settingKey: 'accountCategoryOrders', settingName: 'Account Category Order', mobile: true, desktop: true }, - { settingKey: 'hideCategoriesWithoutAccounts', settingName: 'Hide Categories Without Accounts', mobile: false, desktop: true } + { settingKey: 'hideCategoriesWithoutAccounts', settingName: 'Hide Categories Without Accounts', mobile: false, desktop: true }, + { settingKey: 'reconciliationStatementButtonDefaultDateRangeTypeInDesktop', settingName: 'Default Date Range for Reconciliation Statement Button', mobile: false, desktop: true }, + { settingKey: 'reconciliationStatementPageDefaultDateRangeTypeInMobile', settingName: 'Default Date Range for Reconciliation Statement Page', mobile: true, desktop: false } ] }, { diff --git a/src/views/base/settings/AppSettingsPageBase.ts b/src/views/base/settings/AppSettingsPageBase.ts index 0f148d19..347889c5 100644 --- a/src/views/base/settings/AppSettingsPageBase.ts +++ b/src/views/base/settings/AppSettingsPageBase.ts @@ -3,6 +3,7 @@ import { ref, computed } from 'vue'; import { useI18n } from '@/locales/helpers.ts'; import { useSettingsStore } from '@/stores/setting.ts'; +import { useUserStore } from '@/stores/user.ts'; import { useAccountsStore } from '@/stores/account.ts'; import { useTransactionsStore } from '@/stores/transaction.ts'; import { useTransactionCategoriesStore } from '@/stores/transactionCategory.ts'; @@ -10,6 +11,7 @@ import { useOverviewStore } from '@/stores/overview.ts'; import { useStatisticsStore } from '@/stores/statistics.ts'; import { type NameValue, type TypeAndDisplayName, keysIfValueEquals, values } from '@/core/base.ts'; +import { DateRangeScene, DateRange } from '@/core/datetime.ts'; import type { LocalizedTimezoneInfo } from '@/core/timezone.ts'; import { CategoryType } from '@/core/category.ts'; import type { Account } from '@/models/account.ts'; @@ -18,9 +20,17 @@ import { isObjectEmpty } from '@/lib/common.ts'; import { getCurrentUnixTime } from '@/lib/datetime.ts'; export function useAppSettingPageBase() { - const { tt, getAllTimezones, getAllTimezoneTypesUsedForStatistics, getAllCurrencySortingTypes, setTimeZone } = useI18n(); + const { + tt, + getAllDateRanges, + getAllTimezones, + getAllTimezoneTypesUsedForStatistics, + getAllCurrencySortingTypes, + setTimeZone + } = useI18n(); const settingsStore = useSettingsStore(); + const userStore = useUserStore(); const accountsStore = useAccountsStore(); const transactionsStore = useTransactionsStore(); const transactionCategoriesStore = useTransactionCategoriesStore(); @@ -50,6 +60,12 @@ export function useAppSettingPageBase() { ]; }); + const allReconciliationStatementDateRanges = computed(() => getAllDateRanges(DateRangeScene.Normal, { + includeCustom: true, + includeBillingCycle: true, + includeLastReconciledTimeRange: userStore.currentUserUseLastReconciledTime + })); + const hasAnyAccount = computed(() => accountsStore.allPlainAccounts.length > 0); const hasAnyVisibleAccount = computed(() => accountsStore.allVisibleAccountsCount > 0); const hasAnyTransactionCategory = computed(() => !isObjectEmpty(transactionCategoriesStore.allTransactionCategoriesMap)); @@ -219,6 +235,14 @@ export function useAppSettingPageBase() { return tt('Partial'); } + function getValidReconciliationStatementPageDefaultDateRangeType(value: number, defaultValue: number): number { + if (DateRange.isLastReconciledTimeRange(value) && !userStore.currentUserUseLastReconciledTime) { + return defaultValue; + } + + return value; + } + return { // states loadingAccounts, @@ -229,6 +253,7 @@ export function useAppSettingPageBase() { allTimezoneTypesUsedForStatistics, allCurrencySortingTypes, allAutoSaveTransactionDraftTypes, + allReconciliationStatementDateRanges, timeZone, hasAnyAccount, hasAnyVisibleAccount, @@ -246,6 +271,7 @@ export function useAppSettingPageBase() { accountsIncludedInHomePageOverviewDisplayContent, accountsIncludedInTotalDisplayContent, accountCategorysDisplayOrderContent, - transactionCategoriesIncludedInHomePageOverviewDisplayContent + transactionCategoriesIncludedInHomePageOverviewDisplayContent, + getValidReconciliationStatementPageDefaultDateRangeType }; } diff --git a/src/views/base/transactions/TransactionListPageBase.ts b/src/views/base/transactions/TransactionListPageBase.ts index 51eb9486..98dcd129 100644 --- a/src/views/base/transactions/TransactionListPageBase.ts +++ b/src/views/base/transactions/TransactionListPageBase.ts @@ -110,7 +110,7 @@ export function useTransactionListPageBase() { const allDateRanges = computed(() => getAllDateRanges(DateRangeScene.Normal, { includeCustom: true, includeBillingCycle: !!accountsStore.getAccountStatementDate(query.value.accountIds), - includeLastReconciledTimeRange: !!allAccountsMap.value[query.value.accountIds]?.lastReconciledTime + includeLastReconciledTimeRange: userStore.currentUserUseLastReconciledTime && !!allAccountsMap.value[query.value.accountIds]?.lastReconciledTime })); const allAccounts = computed(() => accountsStore.allMixedPlainAccounts); diff --git a/src/views/desktop/accounts/ListPage.vue b/src/views/desktop/accounts/ListPage.vue index 77adf1fc..31a0e22f 100644 --- a/src/views/desktop/accounts/ListPage.vue +++ b/src/views/desktop/accounts/ListPage.vue @@ -214,7 +214,7 @@ {{ tt('Reconciliation Statement') }} @@ -224,7 +224,7 @@ + @click="showReconciliationStatementDialog(element.getAccountOrSubAccount(activeSubAccount[element.id]), dateRange.type)">
{{ dateRange.displayName }}
@@ -335,10 +335,12 @@ import { useI18n } from '@/locales/helpers.ts'; import { useAccountListPageBase } from '@/views/base/accounts/AccountListPageBase.ts'; import { useSettingsStore } from '@/stores/setting.ts'; +import { useUserStore } from '@/stores/user.ts'; import { useAccountsStore } from '@/stores/account.ts'; import { DateRange, DateRangeScene, type LocalizedDateRange, type TimeRangeAndDateType } from '@/core/datetime.ts'; import { AccountType, AccountCategory } from '@/core/account.ts'; +import { DEFAULT_RECONCILIATION_STATEMENT_DATE_RANGE_IN_DESKTOP } from '@/core/statistics.ts'; import type { Account } from '@/models/account.ts'; import { isNumber } from '@/lib/common.ts'; @@ -400,6 +402,7 @@ const { } = useAccountListPageBase(); const settingsStore = useSettingsStore(); +const userStore = useUserStore(); const accountsStore = useAccountsStore(); const confirmDialog = useTemplateRef('confirmDialog'); @@ -502,7 +505,7 @@ function accountReconciliationStatementDateRanges(account: Account): LocalizedDa return getAllDateRanges(DateRangeScene.Normal, { includeCustom: true, includeBillingCycle: !!accountsStore.getAccountStatementDate(account.id), - includeLastReconciledTimeRange: !!account.lastReconciledTime + includeLastReconciledTimeRange: userStore.currentUserUseLastReconciledTime && !!account.lastReconciledTime }); } @@ -539,7 +542,21 @@ function edit(account: Account): void { }); } -function showReconciliationStatementCustomDateRangeDialog(account: Account, dateRangeType?: number): void { +function showReconciliationStatementDialog(account: Account, dateRangeType?: number): void { + if (!isNumber(dateRangeType)) { + const defualtDateRange = DateRange.valueOf(settingsStore.appSettings.reconciliationStatementButtonDefaultDateRangeTypeInDesktop); + + if (!defualtDateRange) { + dateRangeType = DEFAULT_RECONCILIATION_STATEMENT_DATE_RANGE_IN_DESKTOP.type; + } else if (defualtDateRange.isBillingCycle && !accountsStore.getAccountStatementDate(account.id)) { + dateRangeType = DEFAULT_RECONCILIATION_STATEMENT_DATE_RANGE_IN_DESKTOP.type; + } else if (defualtDateRange.isLastReconciledTimeRange && (!userStore.currentUserUseLastReconciledTime || !account.lastReconciledTime)) { + dateRangeType = DEFAULT_RECONCILIATION_STATEMENT_DATE_RANGE_IN_DESKTOP.type; + } else { + dateRangeType = defualtDateRange.type; + } + } + if (!isNumber(dateRangeType) || dateRangeType === DateRange.Custom.type) { accountToShowReconciliationStatement.value = account; showCustomDateRangeDialog.value = true; diff --git a/src/views/desktop/app/settings/tabs/AppBasicSettingTab.vue b/src/views/desktop/app/settings/tabs/AppBasicSettingTab.vue index 04a0474b..5e84275d 100644 --- a/src/views/desktop/app/settings/tabs/AppBasicSettingTab.vue +++ b/src/views/desktop/app/settings/tabs/AppBasicSettingTab.vue @@ -323,6 +323,17 @@ v-model="hideCategoriesWithoutAccounts" /> + + + @@ -392,6 +403,7 @@ import type { LocalizedSwitchOption } from '@/core/base.ts'; import { ThemeType } from '@/core/theme.ts'; import { type LocalizedDateRange, DateRangeScene } from '@/core/datetime.ts'; import { CategoryType } from '@/core/category.ts'; +import { DEFAULT_RECONCILIATION_STATEMENT_DATE_RANGE_IN_DESKTOP } from '@/core/statistics.ts'; import { getSystemTheme } from '@/lib/ui/common.ts'; @@ -409,6 +421,7 @@ const { allTimezoneTypesUsedForStatistics, allCurrencySortingTypes, allAutoSaveTransactionDraftTypes, + allReconciliationStatementDateRanges, hasAnyAccount, hasAnyVisibleAccount, hasAnyTransactionCategory, @@ -426,7 +439,8 @@ const { accountsIncludedInHomePageOverviewDisplayContent, accountsIncludedInTotalDisplayContent, accountCategorysDisplayOrderContent, - transactionCategoriesIncludedInHomePageOverviewDisplayContent + transactionCategoriesIncludedInHomePageOverviewDisplayContent, + getValidReconciliationStatementPageDefaultDateRangeType } = useAppSettingPageBase(); const settingsStore = useSettingsStore(); @@ -483,6 +497,11 @@ const hideCategoriesWithoutAccounts = computed({ set: (value) => settingsStore.setHideCategoriesWithoutAccounts(value) }); +const reconciliationStatementButtonDefaultDateRangeTypeInDesktop = computed({ + get: () => getValidReconciliationStatementPageDefaultDateRangeType(settingsStore.appSettings.reconciliationStatementButtonDefaultDateRangeTypeInDesktop, DEFAULT_RECONCILIATION_STATEMENT_DATE_RANGE_IN_DESKTOP.type), + set: (value: number) => settingsStore.setReconciliationStatementButtonDefaultDateRangeTypeInDesktop(value) +}); + function init(): void { loadingAccounts.value = true; diff --git a/src/views/mobile/accounts/ReconciliationStatementPage.vue b/src/views/mobile/accounts/ReconciliationStatementPage.vue index 78d913ee..acde115d 100644 --- a/src/views/mobile/accounts/ReconciliationStatementPage.vue +++ b/src/views/mobile/accounts/ReconciliationStatementPage.vue @@ -357,13 +357,15 @@