diff --git a/src/locales/de.json b/src/locales/de.json index b4b890e2..d40bc676 100644 --- a/src/locales/de.json +++ b/src/locales/de.json @@ -1805,6 +1805,7 @@ "Batch Replace Selected Accounts": "Ausgewählte Konten im Batch ersetzen", "Batch Replace Selected Destination Accounts": "Ausgewählte Zielkonten im Batch ersetzen", "Batch Replace Selected Transaction Tags": "Batch Replace Selected Transaction Tags", + "Batch Add Transaction Tags": "Batch Add Transaction Tags", "Replace Invalid Expense Categories": "Ungültige Ausgabenkategorien ersetzen", "Replace Invalid Income Categories": "Ungültige Einnahmenkategorien ersetzen", "Replace Invalid Transfer Categories": "Ungültige Überweisungskategorien ersetzen", diff --git a/src/locales/en.json b/src/locales/en.json index e7b613e6..4113af69 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -1805,6 +1805,7 @@ "Batch Replace Selected Accounts": "Batch Replace Selected Accounts", "Batch Replace Selected Destination Accounts": "Batch Replace Selected Destination Accounts", "Batch Replace Selected Transaction Tags": "Batch Replace Selected Transaction Tags", + "Batch Add Transaction Tags": "Batch Add Transaction Tags", "Replace Invalid Expense Categories": "Replace Invalid Expense Categories", "Replace Invalid Income Categories": "Replace Invalid Income Categories", "Replace Invalid Transfer Categories": "Replace Invalid Transfer Categories", diff --git a/src/locales/es.json b/src/locales/es.json index 7b5d837c..fd63fdae 100644 --- a/src/locales/es.json +++ b/src/locales/es.json @@ -1805,6 +1805,7 @@ "Batch Replace Selected Accounts": "Reemplazo por lotes de cuentas seleccionadas", "Batch Replace Selected Destination Accounts": "Reemplazar por lotes cuentas de destino seleccionadas", "Batch Replace Selected Transaction Tags": "Batch Replace Selected Transaction Tags", + "Batch Add Transaction Tags": "Batch Add Transaction Tags", "Replace Invalid Expense Categories": "Reemplazar categorías de gastos no válidas", "Replace Invalid Income Categories": "Reemplazar categorías de ingresos no válidas", "Replace Invalid Transfer Categories": "Reemplazar categorías de transferencia no válidas", diff --git a/src/locales/it.json b/src/locales/it.json index 14189466..d3ec8f3f 100644 --- a/src/locales/it.json +++ b/src/locales/it.json @@ -1805,6 +1805,7 @@ "Batch Replace Selected Accounts": "Sostituisci in blocco conti selezionati", "Batch Replace Selected Destination Accounts": "Sostituisci in blocco conti di destinazione selezionati", "Batch Replace Selected Transaction Tags": "Batch Replace Selected Transaction Tags", + "Batch Add Transaction Tags": "Batch Add Transaction Tags", "Replace Invalid Expense Categories": "Sostituisci categorie di spesa non valide", "Replace Invalid Income Categories": "Sostituisci categorie di entrata non valide", "Replace Invalid Transfer Categories": "Sostituisci categorie di trasferimento non valide", diff --git a/src/locales/ja.json b/src/locales/ja.json index fba4160a..a3cc3445 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -1805,6 +1805,7 @@ "Batch Replace Selected Accounts": "バッチ選択した口座を置き換えます", "Batch Replace Selected Destination Accounts": "バッチは選択した宛先口座を置き換えます", "Batch Replace Selected Transaction Tags": "Batch Replace Selected Transaction Tags", + "Batch Add Transaction Tags": "Batch Add Transaction Tags", "Replace Invalid Expense Categories": "無効な支出カテゴリを置き換えます", "Replace Invalid Income Categories": "無効な収入カテゴリを置き換えます", "Replace Invalid Transfer Categories": "無効な振替カテゴリを置き換えます", diff --git a/src/locales/nl.json b/src/locales/nl.json index 3c57d1d8..02a3d3e4 100644 --- a/src/locales/nl.json +++ b/src/locales/nl.json @@ -1805,6 +1805,7 @@ "Batch Replace Selected Accounts": "Geselecteerde rekeningen batchgewijs vervangen", "Batch Replace Selected Destination Accounts": "Geselecteerde bestemmingsrekeningen batchgewijs vervangen", "Batch Replace Selected Transaction Tags": "Batch Replace Selected Transaction Tags", + "Batch Add Transaction Tags": "Batch Add Transaction Tags", "Replace Invalid Expense Categories": "Ongeldige uitgavecategorieën vervangen", "Replace Invalid Income Categories": "Ongeldige inkomencategorieën vervangen", "Replace Invalid Transfer Categories": "Ongeldige overboekingscategorieën vervangen", diff --git a/src/locales/pt_BR.json b/src/locales/pt_BR.json index 30bc8960..1fa2269b 100644 --- a/src/locales/pt_BR.json +++ b/src/locales/pt_BR.json @@ -1805,6 +1805,7 @@ "Batch Replace Selected Accounts": "Substituir em Lote as Contas Selecionadas", "Batch Replace Selected Destination Accounts": "Substituir em Lote as Contas de Destino Selecionadas", "Batch Replace Selected Transaction Tags": "Batch Replace Selected Transaction Tags", + "Batch Add Transaction Tags": "Batch Add Transaction Tags", "Replace Invalid Expense Categories": "Substituir Categorias de Despesas Inválidas", "Replace Invalid Income Categories": "Substituir Categorias de Renda Inválidas", "Replace Invalid Transfer Categories": "Substituir Categorias de Transferência Inválidas", diff --git a/src/locales/ru.json b/src/locales/ru.json index 11a17feb..131c2424 100644 --- a/src/locales/ru.json +++ b/src/locales/ru.json @@ -1805,6 +1805,7 @@ "Batch Replace Selected Accounts": "Пакетная замена выбранных счетов", "Batch Replace Selected Destination Accounts": "Пакетная замена выбранных целевых счетов", "Batch Replace Selected Transaction Tags": "Batch Replace Selected Transaction Tags", + "Batch Add Transaction Tags": "Batch Add Transaction Tags", "Replace Invalid Expense Categories": "Заменить недействительные категории расходов", "Replace Invalid Income Categories": "Заменить недействительные категории доходов", "Replace Invalid Transfer Categories": "Заменить недействительные категории переводов", diff --git a/src/locales/uk.json b/src/locales/uk.json index 243364e1..8ef8175d 100644 --- a/src/locales/uk.json +++ b/src/locales/uk.json @@ -1805,6 +1805,7 @@ "Batch Replace Selected Accounts": "Пакетна заміна вибраних рахунків", "Batch Replace Selected Destination Accounts": "Пакетна заміна вибраних цільових рахунків", "Batch Replace Selected Transaction Tags": "Batch Replace Selected Transaction Tags", + "Batch Add Transaction Tags": "Batch Add Transaction Tags", "Replace Invalid Expense Categories": "Замінити недійсні категорії витрат", "Replace Invalid Income Categories": "Замінити недійсні категорії доходів", "Replace Invalid Transfer Categories": "Замінити недійсні категорії переказів", diff --git a/src/locales/vi.json b/src/locales/vi.json index 1dbafc3b..14f5bb97 100644 --- a/src/locales/vi.json +++ b/src/locales/vi.json @@ -1805,6 +1805,7 @@ "Batch Replace Selected Accounts": "Thay thế hàng loạt các tài khoản đã chọn", "Batch Replace Selected Destination Accounts": "Thay thế hàng loạt các tài khoản đích đã chọn", "Batch Replace Selected Transaction Tags": "Batch Replace Selected Transaction Tags", + "Batch Add Transaction Tags": "Batch Add Transaction Tags", "Replace Invalid Expense Categories": "Thay thế các danh mục chi phí không hợp lệ", "Replace Invalid Income Categories": "Thay thế các danh mục thu nhập 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ệ", diff --git a/src/locales/zh_Hans.json b/src/locales/zh_Hans.json index 602d75fc..dd69172e 100644 --- a/src/locales/zh_Hans.json +++ b/src/locales/zh_Hans.json @@ -1805,6 +1805,7 @@ "Batch Replace Selected Accounts": "批量替换选中的账户", "Batch Replace Selected Destination Accounts": "批量替换选中的目标账户", "Batch Replace Selected Transaction Tags": "批量替换选中的交易标签", + "Batch Add Transaction Tags": "批量添加交易标签", "Replace Invalid Expense Categories": "替换无效的支出分类", "Replace Invalid Income Categories": "替换无效的收入分类", "Replace Invalid Transfer Categories": "替换无效的转账分类", diff --git a/src/locales/zh_Hant.json b/src/locales/zh_Hant.json index 61a14748..134f3e4e 100644 --- a/src/locales/zh_Hant.json +++ b/src/locales/zh_Hant.json @@ -1805,6 +1805,7 @@ "Batch Replace Selected Accounts": "批次替換選中的帳戶", "Batch Replace Selected Destination Accounts": "批次替換選中的目標帳戶", "Batch Replace Selected Transaction Tags": "批次替換選中的交易標籤", + "Batch Add Transaction Tags": "批次新增交易標籤", "Replace Invalid Expense Categories": "替換無效的支出分類", "Replace Invalid Income Categories": "替換無效的收入分類", "Replace Invalid Transfer Categories": "替換無效的轉帳分類", diff --git a/src/models/imported_transaction.ts b/src/models/imported_transaction.ts index 2142bb13..e5ca60cd 100644 --- a/src/models/imported_transaction.ts +++ b/src/models/imported_transaction.ts @@ -42,8 +42,8 @@ export class ImportTransaction implements ImportTransactionResponse { this.originalDestinationAccountCurrency = response.originalDestinationAccountCurrency; this.sourceAmount = response.sourceAmount; this.destinationAmount = response.destinationAmount || 0; - this.tagIds = response.tagIds; - this.originalTagNames = response.originalTagNames; + this.tagIds = response.tagIds || []; + this.originalTagNames = response.originalTagNames || []; this.comment = response.comment; this.geoLocation = response.geoLocation; diff --git a/src/views/desktop/transactions/import/dialogs/BatchReplaceDialog.vue b/src/views/desktop/transactions/import/dialogs/BatchReplaceDialog.vue index cc32b70e..7e89db4f 100644 --- a/src/views/desktop/transactions/import/dialogs/BatchReplaceDialog.vue +++ b/src/views/desktop/transactions/import/dialogs/BatchReplaceDialog.vue @@ -9,6 +9,7 @@

{{ tt('Batch Replace Selected Accounts') }}

{{ tt('Batch Replace Selected Destination Accounts') }}

{{ tt('Batch Replace Selected Transaction Tags') }}

+

{{ tt('Batch Add Transaction Tags') }}

{{ tt('Replace Invalid Expense Categories') }}

{{ tt('Replace Invalid Income Categories') }}

{{ tt('Replace Invalid Transfer Categories') }}

@@ -189,7 +190,7 @@ - + @@ -235,7 +236,7 @@ import { mdiPound } from '@mdi/js'; -export type BatchReplaceDialogMode = 'batchReplace' | 'replaceInvalidItems'; +export type BatchReplaceDialogMode = 'batchReplace' | 'batchAdd' | 'replaceInvalidItems'; export type BatchReplaceDialogDataType = 'expenseCategory' | 'incomeCategory' | 'transferCategory' | 'account' | 'destinationAccount' | 'tag'; type SnackBarType = InstanceType; @@ -291,10 +292,10 @@ function open(options: { mode: BatchReplaceDialogMode; type: BatchReplaceDialogD type.value = options.type; sourceItem.value = undefined; - if (mode.value === 'batchReplace') { - invalidItems.value = undefined; - } else if (mode.value === 'replaceInvalidItems') { + if (mode.value === 'replaceInvalidItems') { invalidItems.value = options.invalidItems; + } else { + invalidItems.value = undefined; } if (type.value === 'tag' && mode.value === 'batchReplace') { @@ -369,6 +370,10 @@ function confirm(): void { sourceItem: sourceItem.value, targetItem: targetItemValue }); + } else if (mode.value === 'batchAdd') { + resolveFunc?.({ + targetItem: targetItemValue + }); } else if (mode.value === 'replaceInvalidItems') { resolveFunc?.({ sourceItem: sourceItem.value, diff --git a/src/views/desktop/transactions/import/tabs/ImportTransactionCheckDataTab.vue b/src/views/desktop/transactions/import/tabs/ImportTransactionCheckDataTab.vue index b038a173..69b2cc03 100644 --- a/src/views/desktop/transactions/import/tabs/ImportTransactionCheckDataTab.vue +++ b/src/views/desktop/transactions/import/tabs/ImportTransactionCheckDataTab.vue @@ -671,6 +671,12 @@ const toolMenus = computed(() => [ disabled: isEditing.value || selectedImportTransactionCount.value < 1, onClick: () => showBatchReplaceDialog('tag', allOriginalTransactionTagNames.value) }, + { + prependIcon: mdiFindReplace, + title: tt('Batch Add Transaction Tags'), + disabled: isEditing.value || selectedImportTransactionCount.value < 1, + onClick: () => showBatchAddDialog('tag') + }, { prependIcon: mdiFindReplace, title: tt('Replace Invalid Expense Categories'), @@ -1485,7 +1491,7 @@ function showBatchReplaceDialog(type: BatchReplaceDialogDataType, allSourceTagIt updated = true; } } else if (type === 'tag') { - let removeIndex: number[] = []; + const removeIndex: number[] = []; for (let tagIndex = 0; tagIndex < importTransaction.originalTagNames.length; tagIndex++) { const originalTagName = importTransaction.originalTagNames ? (importTransaction.originalTagNames[tagIndex] ?? '') : ''; @@ -1522,6 +1528,69 @@ function showBatchReplaceDialog(type: BatchReplaceDialogDataType, allSourceTagIt }); } +function showBatchAddDialog(type: BatchReplaceDialogDataType): void { + if (isEditing.value) { + return; + } + + batchReplaceDialog.value?.open({ + mode: 'batchAdd', + type: type + }).then(result => { + if (!result || !result.targetItem) { + return; + } + + let updatedCount = 0; + + if (props.importTransactions) { + for (const importTransaction of props.importTransactions) { + if (!importTransaction.selected) { + continue; + } + + let updated = false; + + if (type === 'tag') { + let containsTag = false; + + for (const tagName of importTransaction.originalTagNames) { + if (tagName === result.targetItem) { + containsTag = true; + break; + } + } + + if (!containsTag) { + if (!importTransaction.tagIds) { + importTransaction.tagIds = []; + } + + if (!importTransaction.originalTagNames) { + importTransaction.originalTagNames = []; + } + + importTransaction.tagIds.push(result.targetItem); + importTransaction.originalTagNames.push(allTagsMap.value[result.targetItem]?.name ?? ''); + updated = true; + } + } + + if (updated) { + updatedCount++; + updateTransactionData(importTransaction); + } + } + } + + if (updatedCount > 0) { + snackbar.value?.showMessage('format.misc.youHaveUpdatedTransactions', { + count: getDisplayCount(updatedCount) + }); + } + }); +} + function showReplaceInvalidItemDialog(type: BatchReplaceDialogDataType, invalidItems: NameValue[]): void { if (isEditing.value) { return; @@ -1584,7 +1653,7 @@ function showReplaceInvalidItemDialog(type: BatchReplaceDialogDataType, invalidI updated = true; } } else if (type === 'tag' && importTransaction.tagIds) { - let removeIndex: number[] = []; + const removeIndex: number[] = []; for (let tagIndex = 0; tagIndex < importTransaction.tagIds.length; tagIndex++) { const tagId = importTransaction.tagIds[tagIndex] as string;