convert transaction type in import transaction dialog

This commit is contained in:
MaysWind
2025-03-04 01:27:51 +08:00
parent 3f8de39683
commit e83b959930
9 changed files with 152 additions and 1 deletions
+23
View File
@@ -49,6 +49,29 @@ export function getCategorizedAccounts(allAccounts: Account[]): CategorizedAccou
return ret; return ret;
} }
export function getAccountMapByName(allAccounts: Account[]): Record<string, Account> {
const ret: Record<string, Account> = {};
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<number, CategorizedAccount>): AccountCategoriesWithVisibleCount[] { export function getCategorizedAccountsWithVisibleCount(categorizedAccountsMap: Record<number, CategorizedAccount>): AccountCategoriesWithVisibleCount[] {
const ret: AccountCategoriesWithVisibleCount[] = []; const ret: AccountCategoriesWithVisibleCount[] = [];
const allCategories = AccountCategory.values(); const allCategories = AccountCategory.values();
+21
View File
@@ -26,6 +26,27 @@ export function categoryTypeToTransactionType(categoryType: CategoryType): Trans
} }
} }
export function getSecondaryTransactionMapByName(allCategories: TransactionCategory[]): Record<string, TransactionCategory> {
const ret: Record<string, TransactionCategory> = {};
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 { export function getTransactionPrimaryCategoryName(categoryId: string | null | undefined, allCategories: TransactionCategory[]): string {
if (!allCategories) { if (!allCategories) {
return ''; return '';
+6
View File
@@ -1680,6 +1680,12 @@
"Replace Invalid Transfer Categories": "Ungültige Überweisungskategorien ersetzen", "Replace Invalid Transfer Categories": "Ungültige Überweisungskategorien ersetzen",
"Replace Invalid Accounts": "Ungültige Konten ersetzen", "Replace Invalid Accounts": "Ungültige Konten ersetzen",
"Replace Invalid Transaction Tags": "Ungültige Transaktions-Tags 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", "Invalid Category": "Ungültige Kategorie",
"Target Category": "Zielkategorie", "Target Category": "Zielkategorie",
"Invalid Account": "Ungültiges Konto", "Invalid Account": "Ungültiges Konto",
+6
View File
@@ -1680,6 +1680,12 @@
"Replace Invalid Transfer Categories": "Replace Invalid Transfer Categories", "Replace Invalid Transfer Categories": "Replace Invalid Transfer Categories",
"Replace Invalid Accounts": "Replace Invalid Accounts", "Replace Invalid Accounts": "Replace Invalid Accounts",
"Replace Invalid Transaction Tags": "Replace Invalid Transaction Tags", "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", "Invalid Category": "Invalid Category",
"Target Category": "Target Category", "Target Category": "Target Category",
"Invalid Account": "Invalid Account", "Invalid Account": "Invalid Account",
+6
View File
@@ -1680,6 +1680,12 @@
"Replace Invalid Transfer Categories": "Reemplazar categorías de transferencia no válidas", "Replace Invalid Transfer Categories": "Reemplazar categorías de transferencia no válidas",
"Replace Invalid Accounts": "Reemplazar cuentas no válidas", "Replace Invalid Accounts": "Reemplazar cuentas no válidas",
"Replace Invalid Transaction Tags": "Reemplazar etiquetas de transacciones 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", "Invalid Category": "Categoría no válida",
"Target Category": "Categoría de destino", "Target Category": "Categoría de destino",
"Invalid Account": "Cuenta no válida", "Invalid Account": "Cuenta no válida",
+6
View File
@@ -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": "Недействительный счет",
+6
View File
@@ -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 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 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ệ", "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ệ", "Invalid Category": "Danh mục không hợp lệ",
"Target Category": "Danh mục mục tiêu", "Target Category": "Danh mục mục tiêu",
"Invalid Account": "Tài khoản không hợp lệ", "Invalid Account": "Tài khoản không hợp lệ",
+6
View File
@@ -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 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": "无效分类", "Invalid Category": "无效分类",
"Target Category": "目标分类", "Target Category": "目标分类",
"Invalid Account": "无效账户", "Invalid Account": "无效账户",
@@ -99,7 +99,7 @@
:icon="true" :disabled="loading || submitting" :icon="true" :disabled="loading || submitting"
v-if="currentStep === 'checkData'"> v-if="currentStep === 'checkData'">
<v-icon :icon="mdiDotsVertical" /> <v-icon :icon="mdiDotsVertical" />
<v-menu activator="parent"> <v-menu activator="parent" max-height="500">
<v-list> <v-list>
<v-list-item :prepend-icon="mdiFindReplace" <v-list-item :prepend-icon="mdiFindReplace"
:disabled="!!editingTransaction || selectedExpenseTransactionCount < 1" :disabled="!!editingTransaction || selectedExpenseTransactionCount < 1"
@@ -142,6 +142,31 @@
:disabled="!!editingTransaction || !allInvalidTransactionTagNames || allInvalidTransactionTagNames.length < 1" :disabled="!!editingTransaction || !allInvalidTransactionTagNames || allInvalidTransactionTagNames.length < 1"
:title="tt('Replace Invalid Transaction Tags')" :title="tt('Replace Invalid Transaction Tags')"
@click="showReplaceInvalidItemDialog('tag', allInvalidTransactionTagNames)"></v-list-item> @click="showReplaceInvalidItemDialog('tag', allInvalidTransactionTagNames)"></v-list-item>
<v-divider class="my-2"/>
<v-list-item :prepend-icon="mdiFindReplace"
:disabled="!!editingTransaction || selectedExpenseTransactionCount < 1"
:title="tt('Batch Convert Expense Transaction to Income Transaction')"
@click="convertTransactionType(TransactionType.Expense, TransactionType.Income)"></v-list-item>
<v-list-item :prepend-icon="mdiFindReplace"
:disabled="!!editingTransaction || selectedExpenseTransactionCount < 1"
:title="tt('Batch Convert Expense Transaction to Transfer Transaction')"
@click="convertTransactionType(TransactionType.Expense, TransactionType.Transfer)"></v-list-item>
<v-list-item :prepend-icon="mdiFindReplace"
:disabled="!!editingTransaction || selectedIncomeTransactionCount < 1"
:title="tt('Batch Convert Income Transaction to Expense Transaction')"
@click="convertTransactionType(TransactionType.Income, TransactionType.Expense)"></v-list-item>
<v-list-item :prepend-icon="mdiFindReplace"
:disabled="!!editingTransaction || selectedIncomeTransactionCount < 1"
:title="tt('Batch Convert Income Transaction to Transfer Transaction')"
@click="convertTransactionType(TransactionType.Income, TransactionType.Transfer)"></v-list-item>
<v-list-item :prepend-icon="mdiFindReplace"
:disabled="!!editingTransaction || selectedTransferTransactionCount < 1"
:title="tt('Batch Convert Transfer Transaction to Expense Transaction')"
@click="convertTransactionType(TransactionType.Transfer, TransactionType.Expense)"></v-list-item>
<v-list-item :prepend-icon="mdiFindReplace"
:disabled="!!editingTransaction || selectedTransferTransactionCount < 1"
:title="tt('Batch Convert Transfer Transaction to Income Transaction')"
@click="convertTransactionType(TransactionType.Transfer, TransactionType.Income)"></v-list-item>
</v-list> </v-list>
</v-menu> </v-menu>
</v-btn> </v-btn>
@@ -818,6 +843,11 @@ import {
getTimezoneOffsetMinutes getTimezoneOffsetMinutes
} from '@/lib/datetime.ts'; } from '@/lib/datetime.ts';
import { import {
getAccountMapByName
} from '@/lib/account.ts';
import {
transactionTypeToCategoryType,
getSecondaryTransactionMapByName,
getTransactionPrimaryCategoryName, getTransactionPrimaryCategoryName,
getTransactionSecondaryCategoryName getTransactionSecondaryCategoryName
} from '@/lib/category.ts'; } from '@/lib/category.ts';
@@ -1029,6 +1059,7 @@ const allAccounts = computed<Account[]>(() => accountsStore.allPlainAccounts);
const allVisibleAccounts = computed<Account[]>(() => accountsStore.allVisiblePlainAccounts); const allVisibleAccounts = computed<Account[]>(() => accountsStore.allVisiblePlainAccounts);
const allVisibleCategorizedAccounts = computed<CategorizedAccountWithDisplayBalance[]>(() => getCategorizedAccountsWithDisplayBalance(allVisibleAccounts.value, showAccountBalance.value)); const allVisibleCategorizedAccounts = computed<CategorizedAccountWithDisplayBalance[]>(() => getCategorizedAccountsWithDisplayBalance(allVisibleAccounts.value, showAccountBalance.value));
const allAccountsMap = computed<Record<string, Account>>(() => accountsStore.allAccountsMap); const allAccountsMap = computed<Record<string, Account>>(() => accountsStore.allAccountsMap);
const allAccountsMapByName = computed<Record<string, Account>>(() => getAccountMapByName(accountsStore.allAccounts));
const allCategories = computed<Record<number, TransactionCategory[]>>(() => transactionCategoriesStore.allTransactionCategories); const allCategories = computed<Record<number, TransactionCategory[]>>(() => transactionCategoriesStore.allTransactionCategories);
const allCategoriesMap = computed<Record<string, TransactionCategory>>(() => transactionCategoriesStore.allTransactionCategoriesMap); const allCategoriesMap = computed<Record<string, TransactionCategory>>(() => transactionCategoriesStore.allTransactionCategoriesMap);
const allTags = computed<TransactionTag[]>(() => transactionTagsStore.allTransactionTags); const allTags = computed<TransactionTag[]>(() => 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<string, TransactionCategory> = 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 { function onShowDateRangeError(message: string): void {
snackbar.value?.showError(message); snackbar.value?.showError(message);
} }