diff --git a/src/lib/account.ts b/src/lib/account.ts index 2c68dacd..6cf5e38c 100644 --- a/src/lib/account.ts +++ b/src/lib/account.ts @@ -49,6 +49,29 @@ export function getCategorizedAccounts(allAccounts: Account[]): CategorizedAccou return ret; } +export function getAccountMapByName(allAccounts: Account[]): Record { + const ret: Record = {}; + + if (!allAccounts) { + return ret; + } + + for (let i = 0; i < allAccounts.length; i++) { + const account = allAccounts[i]; + + if (account.type === AccountType.SingleAccount.type) { + ret[account.name] = account; + } else if (account.type === AccountType.MultiSubAccounts.type && account.subAccounts) { + for (let j = 0; j < account.subAccounts.length; j++) { + const subAccount = account.subAccounts[j]; + ret[subAccount.name] = subAccount; + } + } + } + + return ret; +} + export function getCategorizedAccountsWithVisibleCount(categorizedAccountsMap: Record): AccountCategoriesWithVisibleCount[] { const ret: AccountCategoriesWithVisibleCount[] = []; const allCategories = AccountCategory.values(); diff --git a/src/lib/category.ts b/src/lib/category.ts index c0206a86..65aab7ab 100644 --- a/src/lib/category.ts +++ b/src/lib/category.ts @@ -26,6 +26,27 @@ export function categoryTypeToTransactionType(categoryType: CategoryType): Trans } } +export function getSecondaryTransactionMapByName(allCategories: TransactionCategory[]): Record { + const ret: Record = {}; + + if (!allCategories) { + return ret; + } + + for (let i = 0; i < allCategories.length; i++) { + const category = allCategories[i]; + + if (category.subCategories) { + for (let j = 0; j < category.subCategories.length; j++) { + const subCategory = category.subCategories[j]; + ret[subCategory.name] = subCategory; + } + } + } + + return ret; +} + export function getTransactionPrimaryCategoryName(categoryId: string | null | undefined, allCategories: TransactionCategory[]): string { if (!allCategories) { return ''; diff --git a/src/locales/de.json b/src/locales/de.json index 4eeb306a..9f1a4efa 100644 --- a/src/locales/de.json +++ b/src/locales/de.json @@ -1680,6 +1680,12 @@ "Replace Invalid Transfer Categories": "Ungültige Überweisungskategorien ersetzen", "Replace Invalid Accounts": "Ungültige Konten ersetzen", "Replace Invalid Transaction Tags": "Ungültige Transaktions-Tags ersetzen", + "Batch Convert Expense Transaction to Income Transaction": "Batch Convert Expense Transaction to Income Transaction", + "Batch Convert Expense Transaction to Transfer Transaction": "Batch Convert Expense Transaction to Transfer Transaction", + "Batch Convert Income Transaction to Expense Transaction": "Batch Convert Income Transaction to Expense Transaction", + "Batch Convert Income Transaction to Transfer Transaction": "Batch Convert Income Transaction to Transfer Transaction", + "Batch Convert Transfer Transaction to Expense Transaction": "Batch Convert Transfer Transaction to Expense Transaction", + "Batch Convert Transfer Transaction to Income Transaction": "Batch Convert Transfer Transaction to Income Transaction", "Invalid Category": "Ungültige Kategorie", "Target Category": "Zielkategorie", "Invalid Account": "Ungültiges Konto", diff --git a/src/locales/en.json b/src/locales/en.json index 21a98302..c186d203 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -1680,6 +1680,12 @@ "Replace Invalid Transfer Categories": "Replace Invalid Transfer Categories", "Replace Invalid Accounts": "Replace Invalid Accounts", "Replace Invalid Transaction Tags": "Replace Invalid Transaction Tags", + "Batch Convert Expense Transaction to Income Transaction": "Batch Convert Expense Transaction to Income Transaction", + "Batch Convert Expense Transaction to Transfer Transaction": "Batch Convert Expense Transaction to Transfer Transaction", + "Batch Convert Income Transaction to Expense Transaction": "Batch Convert Income Transaction to Expense Transaction", + "Batch Convert Income Transaction to Transfer Transaction": "Batch Convert Income Transaction to Transfer Transaction", + "Batch Convert Transfer Transaction to Expense Transaction": "Batch Convert Transfer Transaction to Expense Transaction", + "Batch Convert Transfer Transaction to Income Transaction": "Batch Convert Transfer Transaction to Income Transaction", "Invalid Category": "Invalid Category", "Target Category": "Target Category", "Invalid Account": "Invalid Account", diff --git a/src/locales/es.json b/src/locales/es.json index 5abc4de7..c1c0d8a7 100644 --- a/src/locales/es.json +++ b/src/locales/es.json @@ -1680,6 +1680,12 @@ "Replace Invalid Transfer Categories": "Reemplazar categorías de transferencia no válidas", "Replace Invalid Accounts": "Reemplazar cuentas no válidas", "Replace Invalid Transaction Tags": "Reemplazar etiquetas de transacciones no válidas", + "Batch Convert Expense Transaction to Income Transaction": "Batch Convert Expense Transaction to Income Transaction", + "Batch Convert Expense Transaction to Transfer Transaction": "Batch Convert Expense Transaction to Transfer Transaction", + "Batch Convert Income Transaction to Expense Transaction": "Batch Convert Income Transaction to Expense Transaction", + "Batch Convert Income Transaction to Transfer Transaction": "Batch Convert Income Transaction to Transfer Transaction", + "Batch Convert Transfer Transaction to Expense Transaction": "Batch Convert Transfer Transaction to Expense Transaction", + "Batch Convert Transfer Transaction to Income Transaction": "Batch Convert Transfer Transaction to Income Transaction", "Invalid Category": "Categoría no válida", "Target Category": "Categoría de destino", "Invalid Account": "Cuenta no válida", diff --git a/src/locales/ru.json b/src/locales/ru.json index 6646fdd5..c99a74e5 100644 --- a/src/locales/ru.json +++ b/src/locales/ru.json @@ -1680,6 +1680,12 @@ "Replace Invalid Transfer Categories": "Заменить недействительные категории переводов", "Replace Invalid Accounts": "Заменить недействительные счета", "Replace Invalid Transaction Tags": "Заменить недействительные теги транзакций", + "Batch Convert Expense Transaction to Income Transaction": "Batch Convert Expense Transaction to Income Transaction", + "Batch Convert Expense Transaction to Transfer Transaction": "Batch Convert Expense Transaction to Transfer Transaction", + "Batch Convert Income Transaction to Expense Transaction": "Batch Convert Income Transaction to Expense Transaction", + "Batch Convert Income Transaction to Transfer Transaction": "Batch Convert Income Transaction to Transfer Transaction", + "Batch Convert Transfer Transaction to Expense Transaction": "Batch Convert Transfer Transaction to Expense Transaction", + "Batch Convert Transfer Transaction to Income Transaction": "Batch Convert Transfer Transaction to Income Transaction", "Invalid Category": "Недействительная категория", "Target Category": "Целевая категория", "Invalid Account": "Недействительный счет", diff --git a/src/locales/vi.json b/src/locales/vi.json index 812ef49a..7dcc79b5 100644 --- a/src/locales/vi.json +++ b/src/locales/vi.json @@ -1680,6 +1680,12 @@ "Replace Invalid Transfer Categories": "Thay thế các danh mục chuyển khoản không hợp lệ", "Replace Invalid Accounts": "Thay thế các tài khoản không hợp lệ", "Replace Invalid Transaction Tags": "Thay thế các thẻ giao dịch không hợp lệ", + "Batch Convert Expense Transaction to Income Transaction": "Batch Convert Expense Transaction to Income Transaction", + "Batch Convert Expense Transaction to Transfer Transaction": "Batch Convert Expense Transaction to Transfer Transaction", + "Batch Convert Income Transaction to Expense Transaction": "Batch Convert Income Transaction to Expense Transaction", + "Batch Convert Income Transaction to Transfer Transaction": "Batch Convert Income Transaction to Transfer Transaction", + "Batch Convert Transfer Transaction to Expense Transaction": "Batch Convert Transfer Transaction to Expense Transaction", + "Batch Convert Transfer Transaction to Income Transaction": "Batch Convert Transfer Transaction to Income Transaction", "Invalid Category": "Danh mục không hợp lệ", "Target Category": "Danh mục mục tiêu", "Invalid Account": "Tài khoản không hợp lệ", diff --git a/src/locales/zh_Hans.json b/src/locales/zh_Hans.json index 9a9f34f8..869f6c45 100644 --- a/src/locales/zh_Hans.json +++ b/src/locales/zh_Hans.json @@ -1680,6 +1680,12 @@ "Replace Invalid Transfer Categories": "替换无效的转账分类", "Replace Invalid Accounts": "替换无效的账户", "Replace Invalid Transaction Tags": "替换无效的交易标签", + "Batch Convert Expense Transaction to Income Transaction": "批量转换支出交易为收入交易", + "Batch Convert Expense Transaction to Transfer Transaction": "批量转换支出交易为转账交易", + "Batch Convert Income Transaction to Expense Transaction": "批量转换收入交易为支出交易", + "Batch Convert Income Transaction to Transfer Transaction": "批量转换收入交易为转账交易", + "Batch Convert Transfer Transaction to Expense Transaction": "批量转换转账交易为支出交易", + "Batch Convert Transfer Transaction to Income Transaction": "批量转换转账交易为收入交易", "Invalid Category": "无效分类", "Target Category": "目标分类", "Invalid Account": "无效账户", diff --git a/src/views/desktop/transactions/list/dialogs/ImportDialog.vue b/src/views/desktop/transactions/list/dialogs/ImportDialog.vue index 6e937834..d6362e8e 100644 --- a/src/views/desktop/transactions/list/dialogs/ImportDialog.vue +++ b/src/views/desktop/transactions/list/dialogs/ImportDialog.vue @@ -99,7 +99,7 @@ :icon="true" :disabled="loading || submitting" v-if="currentStep === 'checkData'"> - + + + + + + + + @@ -818,6 +843,11 @@ import { getTimezoneOffsetMinutes } from '@/lib/datetime.ts'; import { + getAccountMapByName +} from '@/lib/account.ts'; +import { + transactionTypeToCategoryType, + getSecondaryTransactionMapByName, getTransactionPrimaryCategoryName, getTransactionSecondaryCategoryName } from '@/lib/category.ts'; @@ -1029,6 +1059,7 @@ const allAccounts = computed(() => accountsStore.allPlainAccounts); const allVisibleAccounts = computed(() => accountsStore.allVisiblePlainAccounts); const allVisibleCategorizedAccounts = computed(() => getCategorizedAccountsWithDisplayBalance(allVisibleAccounts.value, showAccountBalance.value)); const allAccountsMap = computed>(() => accountsStore.allAccountsMap); +const allAccountsMapByName = computed>(() => getAccountMapByName(accountsStore.allAccounts)); const allCategories = computed>(() => transactionCategoriesStore.allTransactionCategories); const allCategoriesMap = computed>(() => transactionCategoriesStore.allTransactionCategoriesMap); const allTags = computed(() => transactionTagsStore.allTransactionTags); @@ -2392,6 +2423,46 @@ function showReplaceInvalidItemDialog(type: string, invalidItems: NameValue[]): }); } +function convertTransactionType(fromType: TransactionType, toType: TransactionType): void { + if (!importTransactions.value || importTransactions.value.length < 1) { + return; + } + + const categoryType = transactionTypeToCategoryType(toType); + + if (!categoryType) { + return; + } + + const categoryMapByName: Record = getSecondaryTransactionMapByName(allCategories.value[categoryType]); + + for (let i = 0; i < importTransactions.value.length; i++) { + const transaction: ImportTransaction = importTransactions.value[i]; + + if (!transaction.selected || transaction.type !== fromType) { + continue; + } + + transaction.type = toType; + transaction.categoryId = categoryMapByName[transaction.originalCategoryName]?.id || '0'; + + if (transaction.type === TransactionType.Transfer) { + transaction.destinationAccountId = allAccountsMapByName.value[transaction.originalDestinationAccountName || '']?.id || '0'; + transaction.destinationAmount = transaction.sourceAmount; + } else { + if (fromType === TransactionType.Transfer && toType === TransactionType.Income) { + transaction.sourceAccountId = transaction.destinationAccountId; + transaction.sourceAmount = transaction.destinationAmount; + } + + transaction.destinationAccountId = '0'; + transaction.destinationAmount = 0; + } + + updateTransactionData(transaction); + } +} + function onShowDateRangeError(message: string): void { snackbar.value?.showError(message); }