diff --git a/src/core/import_transaction.ts b/src/core/import_transaction.ts index bd534879..870e55f7 100644 --- a/src/core/import_transaction.ts +++ b/src/core/import_transaction.ts @@ -325,3 +325,100 @@ export class ImportTransactionDataMapping { } } } + +export type ImportTransactionReplaceRuleDataType = 'expenseCategory' | 'incomeCategory' | 'transferCategory' | 'account' | 'tag'; + +export class ImportTransactionReplaceRule { + public dataType: ImportTransactionReplaceRuleDataType; + public sourceValue: string; + public targetId: string; + + private constructor(dataType: ImportTransactionReplaceRuleDataType, sourceValue: string, targetId: string) { + this.dataType = dataType; + this.sourceValue = sourceValue; + this.targetId = targetId; + } + + public toJsonObject(): unknown { + return { + type: this.dataType, + sourceValue: this.sourceValue, + targetId: this.targetId + }; + } + + public static of(dataType: ImportTransactionReplaceRuleDataType, sourceValue: string, targetId: string): ImportTransactionReplaceRule { + return new ImportTransactionReplaceRule(dataType, sourceValue, targetId); + } + + public static parse(data: unknown): ImportTransactionReplaceRule | null { + if (!data + || typeof(data) !== 'object' || !('type' in data) || !('sourceValue' in data) || !('targetId' in data) + || typeof(data.type) !== 'string' || typeof(data.sourceValue) !== 'string' || typeof(data.targetId) !== 'string') { + return null; + } + + if (data.type !== 'expenseCategory' && data.type !== 'incomeCategory' && data.type !== 'transferCategory' && data.type !== 'account' && data.type !== 'tag') { + return null; + } + + return new ImportTransactionReplaceRule(data.type as ImportTransactionReplaceRuleDataType, data.sourceValue as string, data.targetId as string); + } +} + +export class ImportTransactionReplaceRules { + private static readonly JSON_ROOT_FIELD = 'ezBookkeepingImportTransactionReplaceRules'; + + private readonly rules: ImportTransactionReplaceRule[]; + + private constructor(rules: ImportTransactionReplaceRule[]) { + this.rules = rules; + } + + public getRules(): ImportTransactionReplaceRule[] { + return this.rules; + } + + public toJson(): string { + const result: unknown[] = []; + + for (let i = 0; i < this.rules.length; i++) { + const rule = this.rules[i]; + result.push(rule.toJsonObject()); + } + + return JSON.stringify({ + [ImportTransactionReplaceRules.JSON_ROOT_FIELD]: result + }); + } + + public static of(rules: ImportTransactionReplaceRule[]): ImportTransactionReplaceRules { + return new ImportTransactionReplaceRules(rules); + } + + public static parseFromJson(json: string): ImportTransactionReplaceRules | null { + try { + const parsed = JSON.parse(json); + const root = parsed[ImportTransactionReplaceRules.JSON_ROOT_FIELD]; + + if (!root || !('length' in root)) { + return null; + } + + const result = new ImportTransactionReplaceRules([]); + + for (let i = 0; i < root.length; i++) { + const rule = root[i]; + const replaceRule = ImportTransactionReplaceRule.parse(rule); + + if (replaceRule) { + result.rules.push(replaceRule); + } + } + + return result; + } catch { + return null; + } + } +} diff --git a/src/locales/de.json b/src/locales/de.json index 9ad1933e..faf4e12e 100644 --- a/src/locales/de.json +++ b/src/locales/de.json @@ -122,7 +122,8 @@ "exportFilename": "ezBookkeeping_{nickname}_export_data", "defaultExportStatisticsFileName": "ezBookkeeping_statistics_data", "exportStatisticsFileName": "ezBookkeeping_{nickname}_statistics_data", - "defaultImportDataMappingFileName": "ezBookkeeping_import_data_mapping" + "defaultImportDataMappingFileName": "ezBookkeeping_import_data_mapping", + "defaultImportReplaceRuleFileName": "ezBookkeeping_import_replace_rule" }, "datetime": { "AM": { @@ -1653,11 +1654,15 @@ "Duplicate (With Time and Geographic Location)": "Duplicate (With Time and Geographic Location)", "Category": "Kategorie", "Secondary Category": "Secondary Category", + "Expense Category": "Expense Category", + "Income Category": "Income Category", + "Transfer Category": "Transfer Category", "Multiple Categories": "Mehrere Kategorien", "Account": "Konto", "Multiple Accounts": "Mehrere Konten", "Source Account": "Quellkonto", "Destination Account": "Zielkonto", + "Transaction Tag": "Transaction Tag", "Without Tags": "Ohne Tags", "With Any Selected Tags": "Mit ausgewählten Tags", "With All Selected Tags": "Mit allen ausgewählten Tags", @@ -1750,6 +1755,7 @@ "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 Replace Categories / Accounts / Tags": "Batch Replace Categories / Accounts / Tags", "Create Nonexistent Expense Categories": "Create Nonexistent Expense Categories", "Create Nonexistent Income Categories": "Create Nonexistent Income Categories", "Create Nonexistent Transfer Categories": "Create Nonexistent Transfer Categories", @@ -1770,6 +1776,12 @@ "Invalid Tag": "Ungültiges Tag", "Target Tag": "Ziel-Tag", "(Empty)": "(Leer)", + "Source Value": "Source Value", + "Target Value": "Target Value", + "Add Rule": "Add Rule", + "Load Replace Rule File": "Load Replace Rule File", + "Save Replace Rule File": "Save Replace Rule File", + "Replace rule file is invalid": "Replace rule file is invalid", "Tags": "Tags", "Your transaction description (optional)": "Ihre Transaktionsbeschreibung (optional)", "Transaction category cannot be blank": "Transaktionskategorie darf nicht leer sein", diff --git a/src/locales/en.json b/src/locales/en.json index 72942ef0..b63f6b1d 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -122,7 +122,8 @@ "exportFilename": "ezBookkeeping_{nickname}_export_data", "defaultExportStatisticsFileName": "ezBookkeeping_statistics_data", "exportStatisticsFileName": "ezBookkeeping_{nickname}_statistics_data", - "defaultImportDataMappingFileName": "ezBookkeeping_import_data_mapping" + "defaultImportDataMappingFileName": "ezBookkeeping_import_data_mapping", + "defaultImportReplaceRuleFileName": "ezBookkeeping_import_replace_rule" }, "datetime": { "AM": { @@ -1653,11 +1654,15 @@ "Duplicate (With Time and Geographic Location)": "Duplicate (With Time and Geographic Location)", "Category": "Category", "Secondary Category": "Secondary Category", + "Expense Category": "Expense Category", + "Income Category": "Income Category", + "Transfer Category": "Transfer Category", "Multiple Categories": "Multiple Categories", "Account": "Account", "Multiple Accounts": "Multiple Accounts", "Source Account": "Source Account", "Destination Account": "Destination Account", + "Transaction Tag": "Transaction Tag", "Without Tags": "Without Tags", "With Any Selected Tags": "With Any Selected Tags", "With All Selected Tags": "With All Selected Tags", @@ -1750,6 +1755,7 @@ "Replace Invalid Transfer Categories": "Replace Invalid Transfer Categories", "Replace Invalid Accounts": "Replace Invalid Accounts", "Replace Invalid Transaction Tags": "Replace Invalid Transaction Tags", + "Batch Replace Categories / Accounts / Tags": "Batch Replace Categories / Accounts / Tags", "Create Nonexistent Expense Categories": "Create Nonexistent Expense Categories", "Create Nonexistent Income Categories": "Create Nonexistent Income Categories", "Create Nonexistent Transfer Categories": "Create Nonexistent Transfer Categories", @@ -1770,6 +1776,12 @@ "Invalid Tag": "Invalid Tag", "Target Tag": "Target Tag", "(Empty)": "(Empty)", + "Source Value": "Source Value", + "Target Value": "Target Value", + "Add Rule": "Add Rule", + "Load Replace Rule File": "Load Replace Rule File", + "Save Replace Rule File": "Save Replace Rule File", + "Replace rule file is invalid": "Replace rule file is invalid", "Tags": "Tags", "Your transaction description (optional)": "Your transaction description (optional)", "Transaction category cannot be blank": "Transaction category cannot be blank", diff --git a/src/locales/es.json b/src/locales/es.json index 7997efb1..7c15ab38 100644 --- a/src/locales/es.json +++ b/src/locales/es.json @@ -122,7 +122,8 @@ "exportFilename": "ezBookkeeping_{nickname}_export_data", "defaultExportStatisticsFileName": "ezBookkeeping_statistics_data", "exportStatisticsFileName": "ezBookkeeping_{nickname}_statistics_data", - "defaultImportDataMappingFileName": "ezBookkeeping_import_data_mapping" + "defaultImportDataMappingFileName": "ezBookkeeping_import_data_mapping", + "defaultImportReplaceRuleFileName": "ezBookkeeping_import_replace_rule" }, "datetime": { "AM": { @@ -1653,11 +1654,15 @@ "Duplicate (With Time and Geographic Location)": "Duplicate (With Time and Geographic Location)", "Category": "Categoría", "Secondary Category": "Secondary Category", + "Expense Category": "Expense Category", + "Income Category": "Income Category", + "Transfer Category": "Transfer Category", "Multiple Categories": "Múltiples categorías", "Account": "Cuenta", "Multiple Accounts": "Varias cuentas", "Source Account": "Cuenta de origen", "Destination Account": "Cuenta de destino", + "Transaction Tag": "Transaction Tag", "Without Tags": "Sin Etiquetas", "With Any Selected Tags": "Con alguna de las etiquetas seleccionada", "With All Selected Tags": "Con todas las etiquetas seleccionadas", @@ -1750,6 +1755,7 @@ "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 Replace Categories / Accounts / Tags": "Batch Replace Categories / Accounts / Tags", "Create Nonexistent Expense Categories": "Create Nonexistent Expense Categories", "Create Nonexistent Income Categories": "Create Nonexistent Income Categories", "Create Nonexistent Transfer Categories": "Create Nonexistent Transfer Categories", @@ -1770,6 +1776,12 @@ "Invalid Tag": "Etiqueta no válida", "Target Tag": "Etiqueta de destino", "(Empty)": "(Vacío)", + "Source Value": "Source Value", + "Target Value": "Target Value", + "Add Rule": "Add Rule", + "Load Replace Rule File": "Load Replace Rule File", + "Save Replace Rule File": "Save Replace Rule File", + "Replace rule file is invalid": "Replace rule file is invalid", "Tags": "Etiquetas", "Your transaction description (optional)": "Descripción de su transacción (opcional)", "Transaction category cannot be blank": "La categoría de transacción no puede estar en blanco", diff --git a/src/locales/it.json b/src/locales/it.json index 112c9402..eab39932 100644 --- a/src/locales/it.json +++ b/src/locales/it.json @@ -122,7 +122,8 @@ "exportFilename": "ezBookkeeping_{nickname}_export_data", "defaultExportStatisticsFileName": "ezBookkeeping_statistics_data", "exportStatisticsFileName": "ezBookkeeping_{nickname}_statistics_data", - "defaultImportDataMappingFileName": "ezBookkeeping_import_data_mapping" + "defaultImportDataMappingFileName": "ezBookkeeping_import_data_mapping", + "defaultImportReplaceRuleFileName": "ezBookkeeping_import_replace_rule" }, "datetime": { "AM": { @@ -1653,11 +1654,15 @@ "Duplicate (With Time and Geographic Location)": "Duplica (con ora e posizione geografica)", "Category": "Categoria", "Secondary Category": "Categoria secondaria", + "Expense Category": "Expense Category", + "Income Category": "Income Category", + "Transfer Category": "Transfer Category", "Multiple Categories": "Categorie multiple", "Account": "Conto", "Multiple Accounts": "Conti multipli", "Source Account": "Conto di origine", "Destination Account": "Conto di destinazione", + "Transaction Tag": "Transaction Tag", "Without Tags": "Senza tag", "With Any Selected Tags": "Con qualsiasi tag selezionato", "With All Selected Tags": "Con tutti i tag selezionati", @@ -1750,6 +1755,7 @@ "Replace Invalid Transfer Categories": "Sostituisci categorie di trasferimento non valide", "Replace Invalid Accounts": "Sostituisci conti non validi", "Replace Invalid Transaction Tags": "Sostituisci tag transazione non validi", + "Batch Replace Categories / Accounts / Tags": "Batch Replace Categories / Accounts / Tags", "Create Nonexistent Expense Categories": "Crea categorie di spesa inesistenti", "Create Nonexistent Income Categories": "Crea categorie di entrata inesistenti", "Create Nonexistent Transfer Categories": "Crea categorie di trasferimento inesistenti", @@ -1770,6 +1776,12 @@ "Invalid Tag": "Tag non valido", "Target Tag": "Tag di destinazione", "(Empty)": "(Vuoto)", + "Source Value": "Source Value", + "Target Value": "Target Value", + "Add Rule": "Add Rule", + "Load Replace Rule File": "Load Replace Rule File", + "Save Replace Rule File": "Save Replace Rule File", + "Replace rule file is invalid": "Replace rule file is invalid", "Tags": "Tag", "Your transaction description (optional)": "Descrizione della transazione (opzionale)", "Transaction category cannot be blank": "La categoria della transazione non può essere vuota", diff --git a/src/locales/ja.json b/src/locales/ja.json index bb2bde3e..3804d429 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -122,7 +122,8 @@ "exportFilename": "ezBookkeeping_{nickname}_エクスポートデータ", "defaultExportStatisticsFileName": "ezBookkeeping_statistics_data", "exportStatisticsFileName": "ezBookkeeping_{nickname}_statistics_data", - "defaultImportDataMappingFileName": "ezBookkeeping_import_data_mapping" + "defaultImportDataMappingFileName": "ezBookkeeping_import_data_mapping", + "defaultImportReplaceRuleFileName": "ezBookkeeping_import_replace_rule" }, "datetime": { "AM": { @@ -1653,11 +1654,15 @@ "Duplicate (With Time and Geographic Location)": "複製(時間と地理座標を含む)", "Category": "カテゴリ", "Secondary Category": "二次カテゴリ", + "Expense Category": "Expense Category", + "Income Category": "Income Category", + "Transfer Category": "Transfer Category", "Multiple Categories": "マルチカテゴリ", "Account": "口座", "Multiple Accounts": "マルチ口座", "Source Account": "元口座", "Destination Account": "宛先口座", + "Transaction Tag": "Transaction Tag", "Without Tags": "タグなし", "With Any Selected Tags": "選択したタグを含む", "With All Selected Tags": "選択したすべてのタグを含む", @@ -1750,6 +1755,7 @@ "Replace Invalid Transfer Categories": "無効な振替カテゴリを置き換えます", "Replace Invalid Accounts": "無効な口座を置き換えます", "Replace Invalid Transaction Tags": "無効な取引タグを置き換えます", + "Batch Replace Categories / Accounts / Tags": "Batch Replace Categories / Accounts / Tags", "Create Nonexistent Expense Categories": "Create Nonexistent Expense Categories", "Create Nonexistent Income Categories": "Create Nonexistent Income Categories", "Create Nonexistent Transfer Categories": "Create Nonexistent Transfer Categories", @@ -1770,6 +1776,12 @@ "Invalid Tag": "無効なタグ", "Target Tag": "対象タグ", "(Empty)": "(空)", + "Source Value": "Source Value", + "Target Value": "Target Value", + "Add Rule": "Add Rule", + "Load Replace Rule File": "Load Replace Rule File", + "Save Replace Rule File": "Save Replace Rule File", + "Replace rule file is invalid": "Replace rule file is invalid", "Tags": "タグ", "Your transaction description (optional)": "取引の説明(オプション)", "Transaction category cannot be blank": "取引カテゴリは空欄にできません", diff --git a/src/locales/pt_BR.json b/src/locales/pt_BR.json index 171049e9..b96b7038 100644 --- a/src/locales/pt_BR.json +++ b/src/locales/pt_BR.json @@ -122,7 +122,8 @@ "exportFilename": "ezBookkeeping_{nickname}_export_data", "defaultExportStatisticsFileName": "ezBookkeeping_dados_estatísticos", "exportStatisticsFileName": "ezBookkeeping_{nickname}_dados_estatísticos", - "defaultImportDataMappingFileName": "ezBookkeeping_import_data_mapping" + "defaultImportDataMappingFileName": "ezBookkeeping_import_data_mapping", + "defaultImportReplaceRuleFileName": "ezBookkeeping_import_replace_rule" }, "datetime": { "AM": { @@ -1653,11 +1654,15 @@ "Duplicate (With Time and Geographic Location)": "Duplicar (Com Tempo e Localização Geográfica)", "Category": "Categoria", "Secondary Category": "Categoria Secundária", + "Expense Category": "Expense Category", + "Income Category": "Income Category", + "Transfer Category": "Transfer Category", "Multiple Categories": "Várias Categorias", "Account": "Conta", "Multiple Accounts": "Várias Contas", "Source Account": "Conta de Origem", "Destination Account": "Conta de Destino", + "Transaction Tag": "Transaction Tag", "Without Tags": "Sem Tags", "With Any Selected Tags": "Com Quaisquer Tags Selecionadas", "With All Selected Tags": "Com Todas as Tags Selecionadas", @@ -1750,6 +1755,7 @@ "Replace Invalid Transfer Categories": "Substituir Categorias de Transferência Inválidas", "Replace Invalid Accounts": "Substituir Contas Inválidas", "Replace Invalid Transaction Tags": "Substituir Tags de Transação Inválidas", + "Batch Replace Categories / Accounts / Tags": "Batch Replace Categories / Accounts / Tags", "Create Nonexistent Expense Categories": "Criar Categorias de Despesa Inexistentes", "Create Nonexistent Income Categories": "Criar Categorias de Receita Inexistentes", "Create Nonexistent Transfer Categories": "Criar Categorias de Transferência Inexistentes", @@ -1770,6 +1776,12 @@ "Invalid Tag": "Tag Inválida", "Target Tag": "Tag Alvo", "(Empty)": "(Vazio)", + "Source Value": "Source Value", + "Target Value": "Target Value", + "Add Rule": "Add Rule", + "Load Replace Rule File": "Load Replace Rule File", + "Save Replace Rule File": "Save Replace Rule File", + "Replace rule file is invalid": "Replace rule file is invalid", "Tags": "Tags", "Your transaction description (optional)": "Sua descrição da transação (opcional)", "Transaction category cannot be blank": "A categoria da transação não pode estar em branco", diff --git a/src/locales/ru.json b/src/locales/ru.json index 7d5beca7..dfc8be67 100644 --- a/src/locales/ru.json +++ b/src/locales/ru.json @@ -122,7 +122,8 @@ "exportFilename": "ezBookkeeping_{nickname}_export_data", "defaultExportStatisticsFileName": "ezBookkeeping_statistics_data", "exportStatisticsFileName": "ezBookkeeping_{nickname}_statistics_data", - "defaultImportDataMappingFileName": "ezBookkeeping_import_data_mapping" + "defaultImportDataMappingFileName": "ezBookkeeping_import_data_mapping", + "defaultImportReplaceRuleFileName": "ezBookkeeping_import_replace_rule" }, "datetime": { "AM": { @@ -1653,11 +1654,15 @@ "Duplicate (With Time and Geographic Location)": "Duplicate (With Time and Geographic Location)", "Category": "Категория", "Secondary Category": "Secondary Category", + "Expense Category": "Expense Category", + "Income Category": "Income Category", + "Transfer Category": "Transfer Category", "Multiple Categories": "Несколько категорий", "Account": "Счет", "Multiple Accounts": "Несколько счетов", "Source Account": "Исходный счет", "Destination Account": "Целевой счет", + "Transaction Tag": "Transaction Tag", "Without Tags": "Без тегов", "With Any Selected Tags": "С любыми выбранными тегами", "With All Selected Tags": "Со всеми выбранными тегами", @@ -1750,6 +1755,7 @@ "Replace Invalid Transfer Categories": "Заменить недействительные категории переводов", "Replace Invalid Accounts": "Заменить недействительные счета", "Replace Invalid Transaction Tags": "Заменить недействительные теги транзакций", + "Batch Replace Categories / Accounts / Tags": "Batch Replace Categories / Accounts / Tags", "Create Nonexistent Expense Categories": "Create Nonexistent Expense Categories", "Create Nonexistent Income Categories": "Create Nonexistent Income Categories", "Create Nonexistent Transfer Categories": "Create Nonexistent Transfer Categories", @@ -1770,6 +1776,12 @@ "Invalid Tag": "Недействительный тег", "Target Tag": "Целевой тег", "(Empty)": "(Пусто)", + "Source Value": "Source Value", + "Target Value": "Target Value", + "Add Rule": "Add Rule", + "Load Replace Rule File": "Load Replace Rule File", + "Save Replace Rule File": "Save Replace Rule File", + "Replace rule file is invalid": "Replace rule file is invalid", "Tags": "Теги", "Your transaction description (optional)": "Описание вашей транзакции (необязательно)", "Transaction category cannot be blank": "Категория транзакции не может быть пустой", diff --git a/src/locales/uk.json b/src/locales/uk.json index acaa0714..b05d02ba 100644 --- a/src/locales/uk.json +++ b/src/locales/uk.json @@ -122,7 +122,8 @@ "exportFilename": "ezBookkeeping_{nickname}_export_data", "defaultExportStatisticsFileName": "ezBookkeeping_statistics_data", "exportStatisticsFileName": "ezBookkeeping_{nickname}_statistics_data", - "defaultImportDataMappingFileName": "ezBookkeeping_import_data_mapping" + "defaultImportDataMappingFileName": "ezBookkeeping_import_data_mapping", + "defaultImportReplaceRuleFileName": "ezBookkeeping_import_replace_rule" }, "datetime": { "AM": { @@ -1653,11 +1654,15 @@ "Duplicate (With Time and Geographic Location)": "Дублювати (з часом і геолокацією)", "Category": "Категорія", "Secondary Category": "Вторинна категорія", + "Expense Category": "Expense Category", + "Income Category": "Income Category", + "Transfer Category": "Transfer Category", "Multiple Categories": "Кілька категорій", "Account": "Рахунок", "Multiple Accounts": "Кілька рахунків", "Source Account": "Вихідний рахунок", "Destination Account": "Цільовий рахунок", + "Transaction Tag": "Transaction Tag", "Without Tags": "Без тегів", "With Any Selected Tags": "З будь-якими вибраними тегами", "With All Selected Tags": "З усіма вибраними тегами", @@ -1750,6 +1755,7 @@ "Replace Invalid Transfer Categories": "Замінити недійсні категорії переказів", "Replace Invalid Accounts": "Замінити недійсні рахунки", "Replace Invalid Transaction Tags": "Замінити недійсні теги транзакцій", + "Batch Replace Categories / Accounts / Tags": "Batch Replace Categories / Accounts / Tags", "Create Nonexistent Expense Categories": "Створити відсутні категорії витрат", "Create Nonexistent Income Categories": "Створити відсутні категорії доходів", "Create Nonexistent Transfer Categories": "Створити відсутні категорії переказів", @@ -1770,6 +1776,12 @@ "Invalid Tag": "Недійсний тег", "Target Tag": "Цільовий тег", "(Empty)": "(Порожньо)", + "Source Value": "Source Value", + "Target Value": "Target Value", + "Add Rule": "Add Rule", + "Load Replace Rule File": "Load Replace Rule File", + "Save Replace Rule File": "Save Replace Rule File", + "Replace rule file is invalid": "Replace rule file is invalid", "Tags": "Теги", "Your transaction description (optional)": "Опис транзакції (необов'язково)", "Transaction category cannot be blank": "Категорія транзакції не може бути порожньою", diff --git a/src/locales/vi.json b/src/locales/vi.json index 0731e003..2b566e57 100644 --- a/src/locales/vi.json +++ b/src/locales/vi.json @@ -122,7 +122,8 @@ "exportFilename": "ezBookkeeping_{nickname}_export_data", "defaultExportStatisticsFileName": "ezBookkeeping_statistics_data", "exportStatisticsFileName": "ezBookkeeping_{nickname}_statistics_data", - "defaultImportDataMappingFileName": "ezBookkeeping_import_data_mapping" + "defaultImportDataMappingFileName": "ezBookkeeping_import_data_mapping", + "defaultImportReplaceRuleFileName": "ezBookkeeping_import_replace_rule" }, "datetime": { "AM": { @@ -1653,11 +1654,15 @@ "Duplicate (With Time and Geographic Location)": "Duplicate (With Time and Geographic Location)", "Category": "Danh mục", "Secondary Category": "Secondary Category", + "Expense Category": "Expense Category", + "Income Category": "Income Category", + "Transfer Category": "Transfer Category", "Multiple Categories": "Nhiều danh mục", "Account": "Tài khoản", "Multiple Accounts": "Nhiều tài khoản", "Source Account": "Tài khoản nguồn", "Destination Account": "Tài khoản đích", + "Transaction Tag": "Transaction Tag", "Without Tags": "Không có thẻ", "With Any Selected Tags": "With Any Selected Tags", "With All Selected Tags": "With All Selected Tags", @@ -1750,6 +1755,7 @@ "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 Replace Categories / Accounts / Tags": "Batch Replace Categories / Accounts / Tags", "Create Nonexistent Expense Categories": "Create Nonexistent Expense Categories", "Create Nonexistent Income Categories": "Create Nonexistent Income Categories", "Create Nonexistent Transfer Categories": "Create Nonexistent Transfer Categories", @@ -1770,6 +1776,12 @@ "Invalid Tag": "Thẻ không hợp lệ", "Target Tag": "Thẻ mục tiêu", "(Empty)": "(Trống)", + "Source Value": "Source Value", + "Target Value": "Target Value", + "Add Rule": "Add Rule", + "Load Replace Rule File": "Load Replace Rule File", + "Save Replace Rule File": "Save Replace Rule File", + "Replace rule file is invalid": "Replace rule file is invalid", "Tags": "Thẻ", "Your transaction description (optional)": "Mô tả giao dịch của bạn (tùy chọn)", "Transaction category cannot be blank": "Danh mục giao dịch không được để trống", diff --git a/src/locales/zh_Hans.json b/src/locales/zh_Hans.json index 9d98e7ab..aec10962 100644 --- a/src/locales/zh_Hans.json +++ b/src/locales/zh_Hans.json @@ -122,7 +122,8 @@ "exportFilename": "ezBookkeeping_{nickname}_导出数据", "defaultExportStatisticsFileName": "ezBookkeeping_统计数据", "exportStatisticsFileName": "ezBookkeeping_{nickname}_统计数据", - "defaultImportDataMappingFileName": "ezBookkeeping_导入数据映射文件" + "defaultImportDataMappingFileName": "ezBookkeeping_导入数据映射文件", + "defaultImportReplaceRuleFileName": "ezBookkeeping_导入替换规则文件" }, "datetime": { "AM": { @@ -1653,11 +1654,15 @@ "Duplicate (With Time and Geographic Location)": "复制 (含时间和地理位置)", "Category": "分类", "Secondary Category": "二级分类", + "Expense Category": "支出分类", + "Income Category": "收入分类", + "Transfer Category": "转账分类", "Multiple Categories": "多个分类", "Account": "账户", "Multiple Accounts": "多个账户", "Source Account": "来源账户", "Destination Account": "目标账户", + "Transaction Tag": "交易标签", "Without Tags": "没有标签", "With Any Selected Tags": "包含任意选中的标签", "With All Selected Tags": "包含全部选中的标签", @@ -1750,6 +1755,7 @@ "Replace Invalid Transfer Categories": "替换无效的转账分类", "Replace Invalid Accounts": "替换无效的账户", "Replace Invalid Transaction Tags": "替换无效的交易标签", + "Batch Replace Categories / Accounts / Tags": "批量替换分类 / 账户 / 标签", "Create Nonexistent Expense Categories": "创建不存在的支出分类", "Create Nonexistent Income Categories": "创建不存在的收入分类", "Create Nonexistent Transfer Categories": "创建不存在的转账分类", @@ -1770,6 +1776,12 @@ "Invalid Tag": "无效标签", "Target Tag": "目标标签", "(Empty)": "(空白)", + "Source Value": "来源值", + "Target Value": "目标值", + "Add Rule": "添加规则", + "Load Replace Rule File": "加载替换规则文件", + "Save Replace Rule File": "保存替换规则文件", + "Replace rule file is invalid": "替换规则文件无效", "Tags": "标签", "Your transaction description (optional)": "你的交易描述 (可选)", "Transaction category cannot be blank": "交易分类不能为空", diff --git a/src/locales/zh_Hant.json b/src/locales/zh_Hant.json index 5282727c..f80a1d6f 100644 --- a/src/locales/zh_Hant.json +++ b/src/locales/zh_Hant.json @@ -122,7 +122,8 @@ "exportFilename": "ezBookkeeping_{nickname}_匯出資料", "defaultExportStatisticsFileName": "ezBookkeeping_統計資料", "exportStatisticsFileName": "ezBookkeeping_{nickname}_統計資料", - "defaultImportDataMappingFileName": "ezBookkeeping_匯入資料對應檔案" + "defaultImportDataMappingFileName": "ezBookkeeping_匯入資料對應檔案", + "defaultImportReplaceRuleFileName": "ezBookkeeping_匯入替換規則檔案" }, "datetime": { "AM": { @@ -1653,11 +1654,15 @@ "Duplicate (With Time and Geographic Location)": "複製 (含時間和地理位置)", "Category": "分類", "Secondary Category": "次分類", + "Expense Category": "支出分類", + "Income Category": "收入分類", + "Transfer Category": "轉帳分類", "Multiple Categories": "多個分類", "Account": "帳戶", "Multiple Accounts": "多個帳戶", "Source Account": "來源帳戶", "Destination Account": "目標帳戶", + "Transaction Tag": "交易標籤", "Without Tags": "沒有標籤", "With Any Selected Tags": "包含任意選中的標籤", "With All Selected Tags": "包含全部選中的標籤", @@ -1750,6 +1755,7 @@ "Replace Invalid Transfer Categories": "替換無效的轉帳分類", "Replace Invalid Accounts": "替換無效的帳戶", "Replace Invalid Transaction Tags": "替換無效的交易標籤", + "Batch Replace Categories / Accounts / Tags": "批次替換分類 / 帳戶 / 標籤", "Create Nonexistent Expense Categories": "建立不存在的支出分類", "Create Nonexistent Income Categories": "建立不存在的收入分類", "Create Nonexistent Transfer Categories": "建立不存在的轉帳分類", @@ -1770,6 +1776,12 @@ "Invalid Tag": "無效標籤", "Target Tag": "目標標籤", "(Empty)": "(空白)", + "Source Value": "來源值", + "Target Value": "目標值", + "Add Rule": "新增規則", + "Load Replace Rule File": "載入替換規則檔案", + "Save Replace Rule File": "儲存替換規則檔案", + "Replace rule file is invalid": "替換規則檔案無效", "Tags": "標籤", "Your transaction description (optional)": "您的交易描述 (選填)", "Transaction category cannot be blank": "交易分類不能為空", diff --git a/src/views/desktop/transactions/import/ImportDialog.vue b/src/views/desktop/transactions/import/ImportDialog.vue index 0c016980..36c0371f 100644 --- a/src/views/desktop/transactions/import/ImportDialog.vue +++ b/src/views/desktop/transactions/import/ImportDialog.vue @@ -158,6 +158,11 @@ :title="tt('Replace Invalid Transaction Tags')" @click="showReplaceInvalidItemDialog('tag', allInvalidTransactionTagNames)"> + + + @@ -874,6 +880,7 @@ import PaginationButtons from '@/components/desktop/PaginationButtons.vue'; import ConfirmDialog from '@/components/desktop/ConfirmDialog.vue'; import SnackBar from '@/components/desktop/SnackBar.vue'; import BatchReplaceDialog, { type BatchReplaceDialogDataType } from './dialogs/BatchReplaceDialog.vue'; +import BatchReplaceAllTypesDialog from './dialogs/BatchReplaceAllTypesDialog.vue'; import BatchCreateDialog, { type BatchCreateDialogDataType } from './dialogs/BatchCreateDialog.vue'; import { ref, computed, useTemplateRef, watch } from 'vue'; @@ -962,6 +969,7 @@ import { type ConfirmDialogType = InstanceType; type SnackBarType = InstanceType; type BatchReplaceDialogType = InstanceType; +type BatchReplaceAllTypesDialogType = InstanceType; type BatchCreateDialogType = InstanceType; type ImportTransactionDialogStep = 'uploadFile' | 'defineColumn' | 'checkData' | 'finalResult'; @@ -1007,6 +1015,7 @@ const statisticsStore = useStatisticsStore(); const confirmDialog = useTemplateRef('confirmDialog'); const snackbar = useTemplateRef('snackbar'); const batchReplaceDialog = useTemplateRef('batchReplaceDialog'); +const batchReplaceAllTypesDialog = useTemplateRef('batchReplaceAllTypesDialog'); const batchCreateDialog = useTemplateRef('batchCreateDialog'); const fileInput = useTemplateRef('fileInput'); @@ -2479,6 +2488,78 @@ function showReplaceInvalidItemDialog(type: BatchReplaceDialogDataType, invalidI }); } +function showReplaceAllTypesDialog(): void { + if (editingTransaction.value) { + return; + } + + batchReplaceAllTypesDialog.value?.open({ + expenseCategoryNames: allInvalidExpenseCategoryNames.value, + incomeCategoryNames: allInvalidIncomeCategoryNames.value, + transferCategoryNames: allInvalidTransferCategoryNames.value, + accountNames: allInvalidAccountNames.value, + tagNames: allInvalidTransactionTagNames.value + }).then(result => { + if (!result || !result.rules) { + return; + } + + let updatedCount = 0; + + if (importTransactions.value) { + for (let i = 0; i < importTransactions.value.length; i++) { + const transaction: ImportTransaction = importTransactions.value[i]; + let updated = false; + + for (let j = 0; j < result.rules.length; j++) { + const rule = result.rules[j]; + + if (!rule || !rule.dataType || !rule.sourceValue || !rule.targetId) { + continue; + } + + if (rule.dataType === 'expenseCategory' || rule.dataType === 'incomeCategory' || rule.dataType === 'transferCategory') { + if (transaction.type !== TransactionType.ModifyBalance && transaction.originalCategoryName === rule.sourceValue) { + transaction.categoryId = rule.targetId; + updated = true; + } + } else if (rule.dataType === 'account') { + if (transaction.originalSourceAccountName === rule.sourceValue) { + transaction.sourceAccountId = rule.targetId; + updated = true; + } + + if (transaction.type === TransactionType.Transfer && transaction.originalDestinationAccountName === rule.sourceValue) { + transaction.destinationAccountId = rule.targetId; + updated = true; + } + } else if (rule.dataType === 'tag' && transaction.tagIds) { + for (let k = 0; k < transaction.tagIds.length; k++) { + const originalTagName = transaction.originalTagNames ? transaction.originalTagNames[k] : ""; + + if (originalTagName === rule.sourceValue) { + transaction.tagIds[k] = rule.targetId; + updated = true; + } + } + } + } + + if (updated) { + updatedCount++; + updateTransactionData(transaction); + } + } + } + + if (updatedCount > 0) { + snackbar.value?.showMessage('format.misc.youHaveUpdatedTransactions', { + count: updatedCount + }); + } + }); +} + function showBatchCreateInvalidItemDialog(type: BatchCreateDialogDataType, invalidItems: NameValue[]): void { if (editingTransaction.value) { return; diff --git a/src/views/desktop/transactions/import/dialogs/BatchReplaceAllTypesDialog.vue b/src/views/desktop/transactions/import/dialogs/BatchReplaceAllTypesDialog.vue new file mode 100644 index 00000000..9fabcd5f --- /dev/null +++ b/src/views/desktop/transactions/import/dialogs/BatchReplaceAllTypesDialog.vue @@ -0,0 +1,458 @@ + + +