-
+
@@ -33,13 +33,18 @@
+
+
+ {{ $tIf(item[primaryTitleField], primaryTitleI18n) }}
+
+
-
+
@@ -47,6 +52,11 @@
+
+
+ {{ $tIf(subItem[secondaryTitleField], secondaryTitleI18n) }}
+
+
@@ -80,6 +90,8 @@ export default {
'primaryValueField',
'primaryTitleField',
'primaryTitleI18n',
+ 'primaryHeaderField',
+ 'primaryHeaderI18n',
'primaryFooterField',
'primaryFooterI18n',
'primaryIconField',
@@ -90,6 +102,8 @@ export default {
'secondaryValueField',
'secondaryTitleField',
'secondaryTitleI18n',
+ 'secondaryHeaderField',
+ 'secondaryHeaderI18n',
'secondaryFooterField',
'secondaryFooterI18n',
'secondaryIconField',
@@ -234,4 +248,24 @@ export default {
max-height: 310px;
overflow-y: scroll;
}
+
+.two-column-select-menu .list-item-with-header > .v-list-item,
+.two-column-select-menu .list-item-with-footer > .v-list-item {
+ min-height: 58px;
+ padding-top: 6px;
+ padding-bottom: 6px;
+}
+
+.two-column-select-menu .list-item-with-header.list-item-with-footer > .v-list-item {
+ min-height: 78px;
+ padding-top: 8px;
+ padding-bottom: 8px;
+}
+
+.two-column-select-menu .list-item-header,
+.two-column-select-menu .list-item-footer {
+ color: rgba(var(--v-theme-on-background), var(--v-medium-emphasis-opacity));
+ font-size: 0.75rem;
+ line-height: 1.2rem;
+}
diff --git a/src/lib/i18n.js b/src/lib/i18n.js
index ad73e13e..6659cd35 100644
--- a/src/lib/i18n.js
+++ b/src/lib/i18n.js
@@ -13,6 +13,7 @@ import {
isNumber,
getTextBefore,
getTextAfter,
+ copyObjectTo,
copyArrayTo
} from './common.js';
@@ -37,6 +38,11 @@ import {
numericCurrencyToString
} from './currency.js';
+import {
+ getCategorizedAccounts,
+ getAllFilteredAccountsBalance
+} from '@/lib/account.js';
+
import logger from './logger.js';
import services from './services.js';
@@ -988,6 +994,71 @@ function getDisplayCurrencyPrependAndAppendText(currencyCode, currencyDisplayMod
};
}
+function getCategorizedAccountsWithDisplayBalance(exchangeRatesStore, allVisibleAccounts, showAccountBalance, defaultCurrency, options, translateFn) {
+ const categorizedAccounts = copyObjectTo(getCategorizedAccounts(allVisibleAccounts), {});
+
+ for (let category in categorizedAccounts) {
+ if (!Object.prototype.hasOwnProperty.call(categorizedAccounts, category)) {
+ continue;
+ }
+
+ const accountCategory = categorizedAccounts[category];
+
+ if (accountCategory.accounts) {
+ for (let i = 0; i < accountCategory.accounts.length; i++) {
+ const account = accountCategory.accounts[i];
+
+ if (showAccountBalance && account.isAsset) {
+ account.displayBalance = getDisplayCurrency(account.balance, account.currency, options, translateFn);
+ } else if (showAccountBalance && account.isLiability) {
+ account.displayBalance = getDisplayCurrency(-account.balance, account.currency, options, translateFn);
+ } else {
+ account.displayBalance = '***';
+ }
+ }
+ }
+
+ if (showAccountBalance) {
+ const accountsBalance = getAllFilteredAccountsBalance(categorizedAccounts, account => account.category === accountCategory.category);
+ let totalBalance = 0;
+ let hasUnCalculatedAmount = false;
+
+ for (let i = 0; i < accountsBalance.length; i++) {
+ if (accountsBalance[i].currency === defaultCurrency) {
+ if (accountsBalance[i].isAsset) {
+ totalBalance += accountsBalance[i].balance;
+ } else if (accountsBalance[i].isLiability) {
+ totalBalance -= accountsBalance[i].balance;
+ }
+ } else {
+ const balance = exchangeRatesStore.getExchangedAmount(accountsBalance[i].balance, accountsBalance[i].currency, defaultCurrency);
+
+ if (!isNumber(balance)) {
+ hasUnCalculatedAmount = true;
+ continue;
+ }
+
+ if (accountsBalance[i].isAsset) {
+ totalBalance += Math.floor(balance);
+ } else if (accountsBalance[i].isLiability) {
+ totalBalance -= Math.floor(balance);
+ }
+ }
+ }
+
+ if (hasUnCalculatedAmount) {
+ totalBalance = totalBalance + '+';
+ }
+
+ accountCategory.displayBalance = getDisplayCurrency(totalBalance, defaultCurrency, options, translateFn);
+ } else {
+ accountCategory.displayBalance = '***';
+ }
+ }
+
+ return categorizedAccounts;
+}
+
function joinMultiText(textArray, translateFn) {
if (!textArray || !textArray.length) {
return '';
@@ -1231,6 +1302,7 @@ export function i18nFunctions(i18nGlobal) {
getEnableDisableOptions: () => getEnableDisableOptions(i18nGlobal.t),
getDisplayCurrency: (value, currencyCode, options) => getDisplayCurrency(value, currencyCode, options, i18nGlobal.t),
getDisplayCurrencyPrependAndAppendText: (currencyCode, currencyDisplayMode) => getDisplayCurrencyPrependAndAppendText(currencyCode, currencyDisplayMode, i18nGlobal.t),
+ getCategorizedAccountsWithDisplayBalance: (exchangeRatesStore, allVisibleAccounts, showAccountBalance, defaultCurrency, options) => getCategorizedAccountsWithDisplayBalance(exchangeRatesStore, allVisibleAccounts, showAccountBalance, defaultCurrency, options, i18nGlobal.t),
joinMultiText: (textArray) => joinMultiText(textArray, i18nGlobal.t),
setLanguage: (locale, force) => setLanguage(i18nGlobal, locale, force),
setTimeZone: (timezone) => setTimeZone(timezone),
diff --git a/src/lib/transaction.js b/src/lib/transaction.js
index 1be295da..69b75678 100644
--- a/src/lib/transaction.js
+++ b/src/lib/transaction.js
@@ -92,11 +92,11 @@ export function setTransactionModelByTransaction(transaction, transaction2, allC
transaction.type = transaction2.type;
if (transaction.type === transactionConstants.allTransactionTypes.Expense) {
- transaction.expenseCategory = transaction2.categoryId;
+ transaction.expenseCategory = transaction2.categoryId || '';
} else if (transaction.type === transactionConstants.allTransactionTypes.Income) {
- transaction.incomeCategory = transaction2.categoryId;
+ transaction.incomeCategory = transaction2.categoryId || '';
} else if (transaction.type === transactionConstants.allTransactionTypes.Transfer) {
- transaction.transferCategory = transaction2.categoryId;
+ transaction.transferCategory = transaction2.categoryId || '';
}
if (setContextData) {
@@ -118,7 +118,7 @@ export function setTransactionModelByTransaction(transaction, transaction2, allC
if (transaction2.destinationAmount) {
transaction.destinationAmount = transaction2.destinationAmount;
} else {
- transaction.destinationAccountId = 0;
+ transaction.destinationAmount = 0;
}
transaction.hideAmount = transaction2.hideAmount;
diff --git a/src/views/desktop/transactions/list/dialogs/EditDialog.vue b/src/views/desktop/transactions/list/dialogs/EditDialog.vue
index 0c43d841..9298a27d 100644
--- a/src/views/desktop/transactions/list/dialogs/EditDialog.vue
+++ b/src/views/desktop/transactions/list/dialogs/EditDialog.vue
@@ -81,7 +81,7 @@
secondary-key-field="id" secondary-value-field="id" secondary-title-field="name"
secondary-icon-field="icon" secondary-icon-type="category" secondary-color-field="color"
:readonly="mode === 'view'"
- :disabled="loading || submitting"
+ :disabled="loading || submitting || !hasAvailableExpenseCategories"
:show-primary-name="true"
:label="$t('Category')" :placeholder="$t('Category')"
:items="allCategories[allCategoryTypes.Expense]"
@@ -95,7 +95,7 @@
secondary-key-field="id" secondary-value-field="id" secondary-title-field="name"
secondary-icon-field="icon" secondary-icon-type="category" secondary-color-field="color"
:readonly="mode === 'view'"
- :disabled="loading || submitting"
+ :disabled="loading || submitting || !hasAvailableIncomeCategories"
:show-primary-name="true"
:label="$t('Category')" :placeholder="$t('Category')"
:items="allCategories[allCategoryTypes.Income]"
@@ -109,7 +109,7 @@
secondary-key-field="id" secondary-value-field="id" secondary-title-field="name"
secondary-icon-field="icon" secondary-icon-type="category" secondary-color-field="color"
:readonly="mode === 'view'"
- :disabled="loading || submitting"
+ :disabled="loading || submitting || !hasAvailableTransferCategories"
:show-primary-name="true"
:label="$t('Category')" :placeholder="$t('Category')"
:items="allCategories[allCategoryTypes.Transfer]"
@@ -117,84 +117,40 @@
-
-
-
-
- {{ getAccountNameByKeyValue(transaction.sourceAccountId, 'id', 'name', $t('Not Specified')) }}
-
- {{ $t('Not Specified') }}
-
-
-
-
-
-
-
-
- {{ item.title }}
-
-
-
-
-
-
+
+
-
-
-
-
- {{ getAccountNameByKeyValue(transaction.destinationAccountId, 'id', 'name', $t('Not Specified')) }}
-
- {{ $t('Not Specified') }}
-
-
-
-
-
-
-
-
- {{ item.title }}
-
-
-
-
-
-
+
+
account.category === accountCategory.category);
- let totalBalance = 0;
- let hasUnCalculatedAmount = false;
-
- for (let i = 0; i < accountsBalance.length; i++) {
- if (accountsBalance[i].currency === this.defaultCurrency) {
- if (accountsBalance[i].isAsset) {
- totalBalance += accountsBalance[i].balance;
- } else if (accountsBalance[i].isLiability) {
- totalBalance -= accountsBalance[i].balance;
- }
- } else {
- const balance = this.exchangeRatesStore.getExchangedAmount(accountsBalance[i].balance, accountsBalance[i].currency, this.defaultCurrency);
-
- if (!isNumber(balance)) {
- hasUnCalculatedAmount = true;
- continue;
- }
-
- if (accountsBalance[i].isAsset) {
- totalBalance += Math.floor(balance);
- } else if (accountsBalance[i].isLiability) {
- totalBalance -= Math.floor(balance);
- }
- }
- }
-
- if (hasUnCalculatedAmount) {
- totalBalance = totalBalance + '+';
- }
-
- accountCategory.displayBalance = this.getDisplayCurrency(totalBalance, this.defaultCurrency);
- } else {
- accountCategory.displayBalance = '***';
- }
- }
-
- return categorizedAccounts;
+ return this.$locale.getCategorizedAccountsWithDisplayBalance(this.exchangeRatesStore, this.allVisibleAccounts, this.showAccountBalance, this.defaultCurrency, {
+ currencyDisplayMode: this.settingsStore.appSettings.currencyDisplayMode,
+ enableThousandsSeparator: this.settingsStore.appSettings.thousandsSeparator
+ });
},
allCategories() {
return this.transactionCategoriesStore.allTransactionCategories;