From 2dddb77ca4f9e62d274acd1dc5a81a727d157b07 Mon Sep 17 00:00:00 2001 From: MaysWind Date: Tue, 3 Sep 2024 00:47:47 +0800 Subject: [PATCH] fix there are unnecessary separators in exported file when the tag in transaction does not exist, fix the incorrect exported data when the content contains CR("\r") --- pkg/converters/ezbookkeeping_plain_file.go | 11 +- .../ezbookkeeping_plain_file_test.go | 113 ++++++++++++++++++ 2 files changed, 119 insertions(+), 5 deletions(-) diff --git a/pkg/converters/ezbookkeeping_plain_file.go b/pkg/converters/ezbookkeeping_plain_file.go index 57c4535e..d87f856f 100644 --- a/pkg/converters/ezbookkeeping_plain_file.go +++ b/pkg/converters/ezbookkeeping_plain_file.go @@ -441,10 +441,6 @@ func (e *EzBookKeepingPlainFileConverter) getTags(transactionId int64, allTagInd var ret strings.Builder for i := 0; i < len(tagIndexes); i++ { - if i > 0 { - ret.WriteString(transactionTagSeparator) - } - tagIndex := tagIndexes[i] tag, exists := tagMap[tagIndex] @@ -452,7 +448,11 @@ func (e *EzBookKeepingPlainFileConverter) getTags(transactionId int64, allTagInd continue } - ret.WriteString(tag.Name) + if ret.Len() > 0 { + ret.WriteString(transactionTagSeparator) + } + + ret.WriteString(strings.Replace(tag.Name, transactionTagSeparator, " ", -1)) } return ret.String() @@ -461,6 +461,7 @@ func (e *EzBookKeepingPlainFileConverter) getTags(transactionId int64, allTagInd func (e *EzBookKeepingPlainFileConverter) replaceDelimiters(text string, separator string) string { text = strings.Replace(text, separator, " ", -1) text = strings.Replace(text, "\r\n", " ", -1) + text = strings.Replace(text, "\r", " ", -1) text = strings.Replace(text, "\n", " ", -1) return text diff --git a/pkg/converters/ezbookkeeping_plain_file_test.go b/pkg/converters/ezbookkeeping_plain_file_test.go index 18bc6830..c9b45a0d 100644 --- a/pkg/converters/ezbookkeeping_plain_file_test.go +++ b/pkg/converters/ezbookkeeping_plain_file_test.go @@ -9,6 +9,119 @@ import ( "github.com/mayswind/ezbookkeeping/pkg/utils" ) +func TestEzBookKeepingPlainFileConverterToExportedContent(t *testing.T) { + converter := &EzBookKeepingPlainFileConverter{} + + transactions := make([]*models.Transaction, 3) + transactions[0] = &models.Transaction{ + TransactionId: 1, + TransactionTime: 1725165296000, + Type: models.TRANSACTION_DB_TYPE_INCOME, + TimezoneUtcOffset: 480, + CategoryId: 2, + AccountId: 1, + Amount: 12345, + GeoLongitude: 123.45, + GeoLatitude: 45.67, + Comment: "Hello,World", + } + transactions[1] = &models.Transaction{ + TransactionId: 2, + TransactionTime: 1725194096000, + Type: models.TRANSACTION_DB_TYPE_EXPENSE, + TimezoneUtcOffset: 0, + CategoryId: 4, + AccountId: 1, + Amount: -10, + GeoLongitude: 0, + GeoLatitude: 0, + Comment: "Foo#Bar", + } + transactions[2] = &models.Transaction{ + TransactionId: 3, + TransactionTime: 1725212096000, + Type: models.TRANSACTION_DB_TYPE_TRANSFER_OUT, + TimezoneUtcOffset: -300, + CategoryId: 6, + AccountId: 1, + Amount: 12345, + RelatedAccountId: 2, + RelatedAccountAmount: 1735, + Comment: "T\te\rs\nt\r\ntest", + } + + accountMap := make(map[int64]*models.Account, 2) + accountMap[1] = &models.Account{ + AccountId: 1, + Name: "Test Account", + Currency: "CNY", + } + accountMap[2] = &models.Account{ + AccountId: 2, + Name: "Test Account2", + Currency: "USD", + } + + categoryMap := make(map[int64]*models.TransactionCategory, 6) + categoryMap[1] = &models.TransactionCategory{ + CategoryId: 1, + Type: models.CATEGORY_TYPE_INCOME, + Name: "Test Category", + } + categoryMap[2] = &models.TransactionCategory{ + CategoryId: 2, + Type: models.CATEGORY_TYPE_INCOME, + ParentCategoryId: 1, + Name: "Test Sub Category", + } + categoryMap[3] = &models.TransactionCategory{ + CategoryId: 3, + Type: models.CATEGORY_TYPE_EXPENSE, + Name: "Test Category2", + } + categoryMap[4] = &models.TransactionCategory{ + CategoryId: 4, + Type: models.CATEGORY_TYPE_EXPENSE, + ParentCategoryId: 3, + Name: "Test Sub Category2", + } + categoryMap[5] = &models.TransactionCategory{ + CategoryId: 5, + Type: models.CATEGORY_TYPE_TRANSFER, + Name: "Test Category3", + } + categoryMap[6] = &models.TransactionCategory{ + CategoryId: 6, + Type: models.CATEGORY_TYPE_TRANSFER, + ParentCategoryId: 5, + Name: "Test Sub Category3", + } + + tagMap := make(map[int64]*models.TransactionTag, 2) + tagMap[1] = &models.TransactionTag{ + TagId: 1, + Name: "Test,Tag", + } + tagMap[2] = &models.TransactionTag{ + TagId: 2, + Name: "Test;Tag2", + } + + allTagIndexes := make(map[int64][]int64, 2) + allTagIndexes[1] = []int64{1, 2} + allTagIndexes[2] = []int64{3, 1, 4} + allTagIndexes[3] = []int64{2, 3} + + expectedContent := "Time,Timezone,Type,Category,Sub Category,Account,Account Currency,Amount,Account2,Account2 Currency,Account2 Amount,Geographic Location,Tags,Description\n" + + "2024-09-01 12:34:56,+08:00,Income,Test Category,Test Sub Category,Test Account,CNY,123.45,,,,123.450000 45.670000,Test Tag;Test Tag2,Hello World\n" + + "2024-09-01 12:34:56,+00:00,Expense,Test Category2,Test Sub Category2,Test Account,CNY,-0.10,,,,,Test Tag,Foo#Bar\n" + + "2024-09-01 12:34:56,-05:00,Transfer,Test Category3,Test Sub Category3,Test Account,CNY,123.45,Test Account2,USD,17.35,,Test Tag2,T\te s t test\n" + actualContent, err := converter.toExportedContent(123, ",", transactions, accountMap, categoryMap, tagMap, allTagIndexes) + + assert.Nil(t, err) + assert.Equal(t, expectedContent, string(actualContent)) +} + func TestEzBookKeepingPlainFileConverterParseImportedData_MinimumValidData(t *testing.T) { converter := &EzBookKeepingPlainFileConverter{}