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
@@ -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,
@@ -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)
@@ -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()
@@ -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
@@ -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