import member, project and merchant fields as tags when importing feidee mymoney export file

This commit is contained in:
MaysWind
2025-11-25 01:21:44 +08:00
parent 9ff1334584
commit bb9a19bcb2
22 changed files with 171 additions and 27 deletions

View File

@@ -317,45 +317,43 @@ func (c *DataTableTransactionDataImporter) ParseImportedData(ctx core.Context, u
for i := 0; i < len(tagNameItems); i++ {
tagName := tagNameItems[i]
if tagName == "" || tagNamesMap[tagName] {
if tagName == "" {
continue
}
tag, exists := tagMap[tagName]
if !exists {
tag = c.createNewTransactionTagModel(user.Uid, tagName)
allNewTags = append(allNewTags, tag)
tagMap[tagName] = tag
}
if tag != nil {
tagIds = append(tagIds, utils.Int64ToString(tag.TagId))
}
tagNames = append(tagNames, tagName)
tagNamesMap[tagName] = true
allNewTags, tagIds, tagNames = c.addTag(user, tagName, tagNamesMap, tagMap, allNewTags, tagIds, tagNames)
}
}
if dataTable.HasColumn(datatable.TRANSACTION_DATA_TABLE_PAYEE) && additionalOptions.IsPayeeAsTag() {
payee := dataRow.GetData(datatable.TRANSACTION_DATA_TABLE_PAYEE)
if payee != "" && !tagNamesMap[payee] {
tag, exists := tagMap[payee]
if payee != "" {
allNewTags, tagIds, tagNames = c.addTag(user, payee, tagNamesMap, tagMap, allNewTags, tagIds, tagNames)
}
}
if !exists {
tag = c.createNewTransactionTagModel(user.Uid, payee)
allNewTags = append(allNewTags, tag)
tagMap[payee] = tag
}
if dataTable.HasColumn(datatable.TRANSACTION_DATA_TABLE_MEMBER) && additionalOptions.IsMemberAsTag() {
member := dataRow.GetData(datatable.TRANSACTION_DATA_TABLE_MEMBER)
if tag != nil {
tagIds = append(tagIds, utils.Int64ToString(tag.TagId))
}
if member != "" {
allNewTags, tagIds, tagNames = c.addTag(user, member, tagNamesMap, tagMap, allNewTags, tagIds, tagNames)
}
}
tagNames = append(tagNames, payee)
tagNamesMap[payee] = true
if dataTable.HasColumn(datatable.TRANSACTION_DATA_TABLE_PROJECT) && additionalOptions.IsProjectAsTag() {
project := dataRow.GetData(datatable.TRANSACTION_DATA_TABLE_PROJECT)
if project != "" {
allNewTags, tagIds, tagNames = c.addTag(user, project, tagNamesMap, tagMap, allNewTags, tagIds, tagNames)
}
}
if dataTable.HasColumn(datatable.TRANSACTION_DATA_TABLE_MERCHANT) && additionalOptions.IsMerchantAsTag() {
merchant := dataRow.GetData(datatable.TRANSACTION_DATA_TABLE_MERCHANT)
if merchant != "" {
allNewTags, tagIds, tagNames = c.addTag(user, merchant, tagNamesMap, tagMap, allNewTags, tagIds, tagNames)
}
}
@@ -486,6 +484,27 @@ func (c *DataTableTransactionDataImporter) getTransactionCategory(categories map
return subCategory, exists
}
func (c *DataTableTransactionDataImporter) addTag(user *models.User, tagName string, tagNamesMap map[string]bool, tagMap map[string]*models.TransactionTag, allNewTags []*models.TransactionTag, tagIds []string, tagNames []string) ([]*models.TransactionTag, []string, []string) {
if tagName != "" && !tagNamesMap[tagName] {
tag, exists := tagMap[tagName]
if !exists {
tag = c.createNewTransactionTagModel(user.Uid, tagName)
allNewTags = append(allNewTags, tag)
tagMap[tagName] = tag
}
if tag != nil {
tagIds = append(tagIds, utils.Int64ToString(tag.TagId))
}
tagNames = append(tagNames, tagName)
tagNamesMap[tagName] = true
}
return allNewTags, tagIds, tagNames
}
func (c *DataTableTransactionDataImporter) createNewAccountModel(uid int64, accountName string, currency string) *models.Account {
return &models.Account{
Uid: uid,

View File

@@ -27,6 +27,9 @@ const feideeMymoneyAppTransactionAccountCurrencyColumnName = "账户币种"
const feideeMymoneyAppTransactionAmountColumnName = "金额"
const feideeMymoneyAppTransactionDescriptionColumnName = "备注"
const feideeMymoneyAppTransactionRelatedIdColumnName = "关联Id"
const feideeMymoneyAppTransactionMemberColumnName = "成员"
const feideeMymoneyAppTransactionProjectColumnName = "项目"
const feideeMymoneyAppTransactionMerchantColumnName = "商家"
const feideeMymoneyAppTransactionTypeModifyBalanceText = "余额变更"
const feideeMymoneyAppTransactionTypeModifyOutstandingBalanceText = "负债变更"
@@ -44,6 +47,9 @@ var feideeMymoneyAppDataColumnNameMapping = map[datatable.TransactionDataTableCo
datatable.TRANSACTION_DATA_TABLE_ACCOUNT_CURRENCY: feideeMymoneyAppTransactionAccountCurrencyColumnName,
datatable.TRANSACTION_DATA_TABLE_AMOUNT: feideeMymoneyAppTransactionAmountColumnName,
datatable.TRANSACTION_DATA_TABLE_DESCRIPTION: feideeMymoneyAppTransactionDescriptionColumnName,
datatable.TRANSACTION_DATA_TABLE_MEMBER: feideeMymoneyAppTransactionMemberColumnName,
datatable.TRANSACTION_DATA_TABLE_PROJECT: feideeMymoneyAppTransactionProjectColumnName,
datatable.TRANSACTION_DATA_TABLE_MERCHANT: feideeMymoneyAppTransactionMerchantColumnName,
}
// feideeMymoneyAppTransactionDataCsvFileImporter defines the structure of feidee mymoney app csv importer for transaction data
@@ -123,6 +129,18 @@ func (c *feideeMymoneyAppTransactionDataCsvFileImporter) createNewFeideeMymoneyA
newColumns = append(newColumns, datatable.TRANSACTION_DATA_TABLE_DESCRIPTION)
}
if commonDataTable.HasColumn(feideeMymoneyAppTransactionMemberColumnName) {
newColumns = append(newColumns, datatable.TRANSACTION_DATA_TABLE_MEMBER)
}
if commonDataTable.HasColumn(feideeMymoneyAppTransactionProjectColumnName) {
newColumns = append(newColumns, datatable.TRANSACTION_DATA_TABLE_PROJECT)
}
if commonDataTable.HasColumn(feideeMymoneyAppTransactionMerchantColumnName) {
newColumns = append(newColumns, datatable.TRANSACTION_DATA_TABLE_MERCHANT)
}
transactionRowParser := createFeideeMymoneyTransactionDataRowParser()
transactionDataTable := datatable.CreateNewWritableTransactionDataTableWithRowParser(newColumns, transactionRowParser)
transferTransactionsMap := make(map[string]map[datatable.TransactionDataTableColumn]string, 0)

View File

@@ -326,6 +326,35 @@ func TestFeideeMymoneyCsvFileImporterParseImportedData_ParseDescription(t *testi
assert.Equal(t, "Test\nA new line break", allNewTransactions[0].Comment)
}
func TestFeideeMymoneyCsvFileImporterParseImportedData_WithAdditionalOptions(t *testing.T) {
importer := FeideeMymoneyAppTransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
Uid: 1234567890,
DefaultCurrency: "CNY",
}
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
"\"交易类型\",\"日期\",\"子类别\",\"账户\",\"金额\",\"备注\",\"关联Id\",\"成员\",\"项目\",\"商家\"\n"+
"\"支出\",\"2024-09-01 12:34:56\",\"Test Category\",\"Test Account\",\"123.45\",\"\",\"\",\"test1\",\"test2\",\"test3\""), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
assert.Equal(t, 0, len(allNewTransactions[0].OriginalTagNames))
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
"\"交易类型\",\"日期\",\"子类别\",\"账户\",\"金额\",\"备注\",\"关联Id\",\"成员\",\"项目\",\"商家\"\n"+
"\"支出\",\"2024-09-01 12:34:56\",\"Test Category\",\"Test Account\",\"123.45\",\"\",\"\",\"test1\",\"test2\",\"test3\""), 0, converter.DefaultImporterOptions.WithMemberAsTag().WithProjectAsTag().WithMerchantAsTag(), nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
assert.Equal(t, 3, len(allNewTransactions[0].OriginalTagNames))
assert.Contains(t, allNewTransactions[0].OriginalTagNames, "test1")
assert.Contains(t, allNewTransactions[0].OriginalTagNames, "test2")
assert.Contains(t, allNewTransactions[0].OriginalTagNames, "test3")
}
func TestFeideeMymoneyCsvFileImporterParseImportedData_InvalidRelatedId(t *testing.T) {
importer := FeideeMymoneyAppTransactionDataCsvFileImporter
context := core.NewNullContext()

View File

@@ -18,6 +18,9 @@ var feideeMymoneyElecloudDataColumnNameMapping = map[datatable.TransactionDataTa
datatable.TRANSACTION_DATA_TABLE_AMOUNT: "金额",
datatable.TRANSACTION_DATA_TABLE_RELATED_ACCOUNT_NAME: "账户2",
datatable.TRANSACTION_DATA_TABLE_DESCRIPTION: "备注",
datatable.TRANSACTION_DATA_TABLE_MEMBER: "成员",
datatable.TRANSACTION_DATA_TABLE_PROJECT: "项目",
datatable.TRANSACTION_DATA_TABLE_MERCHANT: "商家",
}
// feideeMymoneyElecloudTransactionDataXlsxFileImporter defines the structure of feidee mymoney (elecloud) xlsx importer for transaction data

View File

@@ -17,6 +17,9 @@ var feideeMymoneyWebDataColumnNameMapping = map[datatable.TransactionDataTableCo
datatable.TRANSACTION_DATA_TABLE_AMOUNT: "金额",
datatable.TRANSACTION_DATA_TABLE_RELATED_ACCOUNT_NAME: "账户2",
datatable.TRANSACTION_DATA_TABLE_DESCRIPTION: "备注",
datatable.TRANSACTION_DATA_TABLE_MEMBER: "成员",
datatable.TRANSACTION_DATA_TABLE_PROJECT: "项目",
datatable.TRANSACTION_DATA_TABLE_MERCHANT: "商家",
}
// feideeMymoneyWebTransactionDataXlsFileImporter defines the structure of feidee mymoney (web) xls importer for transaction data

View File

@@ -279,6 +279,11 @@ export const SUPPORTED_IMPORT_FILE_CATEGORY_AND_TYPES: ImportFileCategoryAndType
type: 'feidee_mymoney_csv',
name: 'Feidee MyMoney (App) Data Export File',
extensions: '.csv',
supportedAdditionalOptions: {
memberAsTag: false,
projectAsTag: false,
merchantAsTag: false,
},
document: {
supportMultiLanguages: 'zh-Hans',
anchor: '如何获取随手记app数据导出文件'
@@ -288,6 +293,11 @@ export const SUPPORTED_IMPORT_FILE_CATEGORY_AND_TYPES: ImportFileCategoryAndType
type: 'feidee_mymoney_xls',
name: 'Feidee MyMoney (Web) Data Export File',
extensions: '.xls',
supportedAdditionalOptions: {
memberAsTag: false,
projectAsTag: false,
merchantAsTag: false,
},
document: {
supportMultiLanguages: 'zh-Hans',
anchor: '如何获取随手记web版数据导出文件'
@@ -297,6 +307,11 @@ export const SUPPORTED_IMPORT_FILE_CATEGORY_AND_TYPES: ImportFileCategoryAndType
type: 'feidee_mymoney_elecloud_xlsx',
name: 'Feidee MyMoney (Elecloud) Data Export File',
extensions: '.xlsx',
supportedAdditionalOptions: {
memberAsTag: false,
projectAsTag: false,
merchantAsTag: false,
},
document: {
supportMultiLanguages: 'zh-Hans',
anchor: '如何获取随手记神象云账本数据导出文件'

View File

@@ -1888,6 +1888,9 @@
"Additional Options": "Additional Options",
"Parse Payee as Tag": "Parse Payee as Tag",
"Parse Payee as Description": "Parse Payee as Description",
"Parse Member as Tag": "Parse Member as Tag",
"Parse Project as Tag": "Parse Project as Tag",
"Parse Merchant as Tag": "Parse Merchant as Tag",
"Data File": "Datendatei",
"Data to import": "Data to import",
"Please select a file to import": "Bitte wählen Sie eine Datei zum Importieren aus",

View File

@@ -1888,6 +1888,9 @@
"Additional Options": "Additional Options",
"Parse Payee as Tag": "Parse Payee as Tag",
"Parse Payee as Description": "Parse Payee as Description",
"Parse Member as Tag": "Parse Member as Tag",
"Parse Project as Tag": "Parse Project as Tag",
"Parse Merchant as Tag": "Parse Merchant as Tag",
"Data File": "Data File",
"Data to import": "Data to import",
"Please select a file to import": "Please select a file to import",

View File

@@ -1888,6 +1888,9 @@
"Additional Options": "Additional Options",
"Parse Payee as Tag": "Parse Payee as Tag",
"Parse Payee as Description": "Parse Payee as Description",
"Parse Member as Tag": "Parse Member as Tag",
"Parse Project as Tag": "Parse Project as Tag",
"Parse Merchant as Tag": "Parse Merchant as Tag",
"Data File": "Archivo de datos",
"Data to import": "Data to import",
"Please select a file to import": "Please select a file to import",

View File

@@ -1888,6 +1888,9 @@
"Additional Options": "Additional Options",
"Parse Payee as Tag": "Parse Payee as Tag",
"Parse Payee as Description": "Parse Payee as Description",
"Parse Member as Tag": "Parse Member as Tag",
"Parse Project as Tag": "Parse Project as Tag",
"Parse Merchant as Tag": "Parse Merchant as Tag",
"Data File": "Fichier de données",
"Data to import": "Données à importer",
"Please select a file to import": "Veuillez sélectionner un fichier à importer",

View File

@@ -1888,6 +1888,9 @@
"Additional Options": "Additional Options",
"Parse Payee as Tag": "Parse Payee as Tag",
"Parse Payee as Description": "Parse Payee as Description",
"Parse Member as Tag": "Parse Member as Tag",
"Parse Project as Tag": "Parse Project as Tag",
"Parse Merchant as Tag": "Parse Merchant as Tag",
"Data File": "File dati",
"Data to import": "Dati da importare",
"Please select a file to import": "Seleziona un file da importare",

View File

@@ -1888,6 +1888,9 @@
"Additional Options": "Additional Options",
"Parse Payee as Tag": "Parse Payee as Tag",
"Parse Payee as Description": "Parse Payee as Description",
"Parse Member as Tag": "Parse Member as Tag",
"Parse Project as Tag": "Parse Project as Tag",
"Parse Merchant as Tag": "Parse Merchant as Tag",
"Data File": "データファイル",
"Data to import": "インポートするデータ",
"Please select a file to import": "インポートするファイルを選択してください",

View File

@@ -1888,6 +1888,9 @@
"Additional Options": "Additional Options",
"Parse Payee as Tag": "Parse Payee as Tag",
"Parse Payee as Description": "Parse Payee as Description",
"Parse Member as Tag": "Parse Member as Tag",
"Parse Project as Tag": "Parse Project as Tag",
"Parse Merchant as Tag": "Parse Merchant as Tag",
"Data File": "데이터 파일",
"Data to import": "가져올 데이터",
"Please select a file to import": "가져올 파일을 선택하십시오",

View File

@@ -1888,6 +1888,9 @@
"Additional Options": "Additional Options",
"Parse Payee as Tag": "Parse Payee as Tag",
"Parse Payee as Description": "Parse Payee as Description",
"Parse Member as Tag": "Parse Member as Tag",
"Parse Project as Tag": "Parse Project as Tag",
"Parse Merchant as Tag": "Parse Merchant as Tag",
"Data File": "Gegevensbestand",
"Data to import": "Te importeren gegevens",
"Please select a file to import": "Selecteer een bestand om te importeren",

View File

@@ -1888,6 +1888,9 @@
"Additional Options": "Additional Options",
"Parse Payee as Tag": "Parse Payee as Tag",
"Parse Payee as Description": "Parse Payee as Description",
"Parse Member as Tag": "Parse Member as Tag",
"Parse Project as Tag": "Parse Project as Tag",
"Parse Merchant as Tag": "Parse Merchant as Tag",
"Data File": "Arquivo de Dados",
"Data to import": "Dados para importar",
"Please select a file to import": "Por favor, selecione um arquivo para importar",

View File

@@ -1888,6 +1888,9 @@
"Additional Options": "Additional Options",
"Parse Payee as Tag": "Parse Payee as Tag",
"Parse Payee as Description": "Parse Payee as Description",
"Parse Member as Tag": "Parse Member as Tag",
"Parse Project as Tag": "Parse Project as Tag",
"Parse Merchant as Tag": "Parse Merchant as Tag",
"Data File": "Файл данных",
"Data to import": "Data to import",
"Please select a file to import": "Please select a file to import",

View File

@@ -1888,6 +1888,9 @@
"Additional Options": "Additional Options",
"Parse Payee as Tag": "Parse Payee as Tag",
"Parse Payee as Description": "Parse Payee as Description",
"Parse Member as Tag": "Parse Member as Tag",
"Parse Project as Tag": "Parse Project as Tag",
"Parse Merchant as Tag": "Parse Merchant as Tag",
"Data File": "ไฟล์ข้อมูล",
"Data to import": "ข้อมูลที่จะนำเข้า",
"Please select a file to import": "กรุณาเลือกไฟล์เพื่อนำเข้า",

View File

@@ -1888,6 +1888,9 @@
"Additional Options": "Additional Options",
"Parse Payee as Tag": "Parse Payee as Tag",
"Parse Payee as Description": "Parse Payee as Description",
"Parse Member as Tag": "Parse Member as Tag",
"Parse Project as Tag": "Parse Project as Tag",
"Parse Merchant as Tag": "Parse Merchant as Tag",
"Data File": "Файл даних",
"Data to import": "Дані для імпорту",
"Please select a file to import": "Будь ласка, виберіть файл для імпорту",

View File

@@ -1888,6 +1888,9 @@
"Additional Options": "Additional Options",
"Parse Payee as Tag": "Parse Payee as Tag",
"Parse Payee as Description": "Parse Payee as Description",
"Parse Member as Tag": "Parse Member as Tag",
"Parse Project as Tag": "Parse Project as Tag",
"Parse Merchant as Tag": "Parse Merchant as Tag",
"Data File": "Tệp dữ liệu",
"Data to import": "Data to import",
"Please select a file to import": "Please select a file to import",

View File

@@ -1888,6 +1888,9 @@
"Additional Options": "附加选项",
"Parse Payee as Tag": "将收款人解析为标签",
"Parse Payee as Description": "将收款人解析为描述",
"Parse Member as Tag": "将成员解析为标签",
"Parse Project as Tag": "将项目解析为标签",
"Parse Merchant as Tag": "将商户解析为标签",
"Data File": "数据文件",
"Data to import": "要导入的数据",
"Please select a file to import": "请选择要导入的文件",

View File

@@ -1888,6 +1888,9 @@
"Additional Options": "附加選項",
"Parse Payee as Tag": "將收款人解析為標籤",
"Parse Payee as Description": "將收款人解析為描述",
"Parse Member as Tag": "將成員解析為標籤",
"Parse Project as Tag": "將專案解析為標籤",
"Parse Merchant as Tag": "將商家解析為標籤",
"Data File": "資料檔案",
"Data to import": "要匯入的資料",
"Please select a file to import": "請選擇要匯入的檔案",

View File

@@ -355,6 +355,18 @@ const allSupportedAdditionalOptions: KeyAndName[] = [
{
key: 'payeeAsDescription',
name: 'Parse Payee as Description'
},
{
key: 'memberAsTag',
name: 'Parse Member as Tag'
},
{
key: 'projectAsTag',
name: 'Parse Project as Tag'
},
{
key: 'merchantAsTag',
name: 'Parse Merchant as Tag'
}
];