support categories with the same name but different types when import transaction
This commit is contained in:
@@ -1093,7 +1093,7 @@ func (a *TransactionsApi) TransactionParseImportFileHandler(c *core.WebContext)
|
||||
return nil, errs.Or(err, errs.ErrOperationFailed)
|
||||
}
|
||||
|
||||
categoryMap := a.transactionCategories.GetCategoryNameMapByList(categories)
|
||||
expenseCategoryMap, incomeCategoryMap, transferCategoryMap := a.transactionCategories.GetCategoryNameMapByList(categories)
|
||||
|
||||
tags, err := a.transactionTags.GetAllTagsByUid(c, user.Uid)
|
||||
|
||||
@@ -1104,7 +1104,7 @@ func (a *TransactionsApi) TransactionParseImportFileHandler(c *core.WebContext)
|
||||
|
||||
tagMap := a.transactionTags.GetTagNameMapByList(tags)
|
||||
|
||||
parsedTransactions, _, _, _, err := dataImporter.ParseImportedData(c, user, fileData, utcOffset, accountMap, categoryMap, tagMap)
|
||||
parsedTransactions, _, _, _, _, _, err := dataImporter.ParseImportedData(c, user, fileData, utcOffset, accountMap, expenseCategoryMap, incomeCategoryMap, transferCategoryMap, tagMap)
|
||||
|
||||
if err != nil {
|
||||
log.BootErrorf(c, "[transactions.TransactionParseImportFileHandler] failed to parse imported data for user \"uid:%d\", because %s", user.Uid, err.Error())
|
||||
|
||||
+24
-12
@@ -677,14 +677,14 @@ func (l *UserDataCli) ImportTransaction(c *core.CliContext, username string, fil
|
||||
return err
|
||||
}
|
||||
|
||||
accountMap, categoryMap, tagMap, err := l.getUserEssentialDataForImport(c, user.Uid, username)
|
||||
accountMap, expenseCategoryMap, incomeCategoryMap, transferCategoryMap, tagMap, err := l.getUserEssentialDataForImport(c, user.Uid, username)
|
||||
|
||||
if err != nil {
|
||||
log.CliErrorf(c, "[user_data.ImportTransaction] failed to get essential data for user \"%s\", because %s", username, err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
parsedTransactions, newAccounts, newCategories, newTags, err := dataImporter.ParseImportedData(c, user, data, utils.GetTimezoneOffsetMinutes(time.Local), accountMap, categoryMap, tagMap)
|
||||
parsedTransactions, newAccounts, newSubExpenseCategories, newSubIncomeCategories, newSubTransferCategories, newTags, err := dataImporter.ParseImportedData(c, user, data, utils.GetTimezoneOffsetMinutes(time.Local), accountMap, expenseCategoryMap, incomeCategoryMap, transferCategoryMap, tagMap)
|
||||
|
||||
if err != nil {
|
||||
log.CliErrorf(c, "[user_data.ImportTransaction] failed to parse imported data for \"%s\", because %s", username, err.Error())
|
||||
@@ -702,9 +702,21 @@ func (l *UserDataCli) ImportTransaction(c *core.CliContext, username string, fil
|
||||
return errs.ErrOperationFailed
|
||||
}
|
||||
|
||||
if len(newCategories) > 0 {
|
||||
categoryNames := l.categories.GetCategoryNames(newCategories)
|
||||
log.CliErrorf(c, "[user_data.ImportTransaction] there are %d transaction categories (%s) need to be created, please create them manually", len(newCategories), strings.Join(categoryNames, ","))
|
||||
if len(newSubExpenseCategories) > 0 {
|
||||
categoryNames := l.categories.GetCategoryNames(newSubExpenseCategories)
|
||||
log.CliErrorf(c, "[user_data.ImportTransaction] there are %d expense categories (%s) need to be created, please create them manually", len(newSubExpenseCategories), strings.Join(categoryNames, ","))
|
||||
return errs.ErrOperationFailed
|
||||
}
|
||||
|
||||
if len(newSubIncomeCategories) > 0 {
|
||||
categoryNames := l.categories.GetCategoryNames(newSubIncomeCategories)
|
||||
log.CliErrorf(c, "[user_data.ImportTransaction] there are %d income categories (%s) need to be created, please create them manually", len(newSubIncomeCategories), strings.Join(categoryNames, ","))
|
||||
return errs.ErrOperationFailed
|
||||
}
|
||||
|
||||
if len(newSubTransferCategories) > 0 {
|
||||
categoryNames := l.categories.GetCategoryNames(newSubTransferCategories)
|
||||
log.CliErrorf(c, "[user_data.ImportTransaction] there are %d transfer categories (%s) need to be created, please create them manually", len(newSubTransferCategories), strings.Join(categoryNames, ","))
|
||||
return errs.ErrOperationFailed
|
||||
}
|
||||
|
||||
@@ -788,17 +800,17 @@ func (l *UserDataCli) getUserEssentialData(c *core.CliContext, uid int64, userna
|
||||
return accountMap, categoryMap, tagMap, tagIndexes, tagIndexesMap, nil
|
||||
}
|
||||
|
||||
func (l *UserDataCli) getUserEssentialDataForImport(c *core.CliContext, uid int64, username string) (accountMap map[string]*models.Account, categoryMap map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag, err error) {
|
||||
func (l *UserDataCli) getUserEssentialDataForImport(c *core.CliContext, uid int64, username string) (accountMap map[string]*models.Account, expenseCategoryMap map[string]*models.TransactionCategory, incomeCategoryMap map[string]*models.TransactionCategory, transferCategoryMap map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag, err error) {
|
||||
if uid <= 0 {
|
||||
log.CliErrorf(c, "[user_data.getUserEssentialDataForImport] user uid \"%d\" is invalid", uid)
|
||||
return nil, nil, nil, errs.ErrUserIdInvalid
|
||||
return nil, nil, nil, nil, nil, errs.ErrUserIdInvalid
|
||||
}
|
||||
|
||||
accounts, err := l.accounts.GetAllAccountsByUid(c, uid)
|
||||
|
||||
if err != nil {
|
||||
log.CliErrorf(c, "[user_data.getUserEssentialDataForImport] failed to get accounts for user \"%s\", because %s", username, err.Error())
|
||||
return nil, nil, nil, err
|
||||
return nil, nil, nil, nil, nil, err
|
||||
}
|
||||
|
||||
accountMap = l.accounts.GetAccountNameMapByList(accounts)
|
||||
@@ -807,21 +819,21 @@ func (l *UserDataCli) getUserEssentialDataForImport(c *core.CliContext, uid int6
|
||||
|
||||
if err != nil {
|
||||
log.CliErrorf(c, "[user_data.getUserEssentialDataForImport] failed to get categories for user \"%s\", because %s", username, err.Error())
|
||||
return nil, nil, nil, err
|
||||
return nil, nil, nil, nil, nil, err
|
||||
}
|
||||
|
||||
categoryMap = l.categories.GetCategoryNameMapByList(categories)
|
||||
expenseCategoryMap, incomeCategoryMap, transferCategoryMap = l.categories.GetCategoryNameMapByList(categories)
|
||||
|
||||
tags, err := l.tags.GetAllTagsByUid(c, uid)
|
||||
|
||||
if err != nil {
|
||||
log.CliErrorf(c, "[user_data.getUserEssentialDataForImport] failed to get tags for user \"%s\", because %s", username, err.Error())
|
||||
return nil, nil, nil, err
|
||||
return nil, nil, nil, nil, nil, err
|
||||
}
|
||||
|
||||
tagMap = l.tags.GetTagNameMapByList(tags)
|
||||
|
||||
return accountMap, categoryMap, tagMap, nil
|
||||
return accountMap, expenseCategoryMap, incomeCategoryMap, transferCategoryMap, tagMap, nil
|
||||
}
|
||||
|
||||
func (l *UserDataCli) checkTransactionAccount(c *core.CliContext, transaction *models.Transaction, accountMap map[int64]*models.Account, accountHasChild map[int64]bool) error {
|
||||
|
||||
@@ -50,18 +50,18 @@ var (
|
||||
)
|
||||
|
||||
// ParseImportedData returns the imported data by parsing the alipay transaction csv data
|
||||
func (c *alipayTransactionDataCsvImporter) ParseImportedData(ctx core.Context, user *models.User, data []byte, defaultTimezoneOffset int16, accountMap map[string]*models.Account, categoryMap map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionTag, error) {
|
||||
func (c *alipayTransactionDataCsvImporter) ParseImportedData(ctx core.Context, user *models.User, data []byte, defaultTimezoneOffset int16, accountMap map[string]*models.Account, expenseCategoryMap map[string]*models.TransactionCategory, incomeCategoryMap map[string]*models.TransactionCategory, transferCategoryMap map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionTag, error) {
|
||||
enc := simplifiedchinese.GB18030
|
||||
reader := transform.NewReader(bytes.NewReader(data), enc.NewDecoder())
|
||||
allLines, err := c.parseAllLinesFromCsvData(ctx, reader)
|
||||
|
||||
if err != nil {
|
||||
return nil, nil, nil, nil, err
|
||||
return nil, nil, nil, nil, nil, nil, err
|
||||
}
|
||||
|
||||
if len(allLines) <= 1 {
|
||||
log.Errorf(ctx, "[alipayTransactionDataCsvImporter.ParseImportedData] cannot parse import data for user \"uid:%d\", because data table row count is less 1", user.Uid)
|
||||
return nil, nil, nil, nil, errs.ErrNotFoundTransactionDataInFile
|
||||
return nil, nil, nil, nil, nil, nil, errs.ErrNotFoundTransactionDataInFile
|
||||
}
|
||||
|
||||
headerLineItems := allLines[0]
|
||||
@@ -81,7 +81,7 @@ func (c *alipayTransactionDataCsvImporter) ParseImportedData(ctx core.Context, u
|
||||
|
||||
if !timeColumnExists || !amountColumnExists || !statusColumnExists || !fundStatusColumnExists {
|
||||
log.Errorf(ctx, "[alipayTransactionDataCsvImporter.ParseImportedData] cannot parse import data for user \"uid:%d\", because missing essential columns in header row", user.Uid)
|
||||
return nil, nil, nil, nil, errs.ErrMissingRequiredFieldInHeaderRow
|
||||
return nil, nil, nil, nil, nil, nil, errs.ErrMissingRequiredFieldInHeaderRow
|
||||
}
|
||||
|
||||
newColumns := make([]datatable.DataTableColumn, 0, 7)
|
||||
@@ -126,7 +126,7 @@ func (c *alipayTransactionDataCsvImporter) ParseImportedData(ctx core.Context, u
|
||||
|
||||
if len(items) < len(headerLineItems) {
|
||||
log.Errorf(ctx, "[alipayTransactionDataCsvImporter.ParseImportedData] cannot parse row \"index:%d\" for user \"uid:%d\", because may missing some columns (column count %d in data row is less than header column count %d)", i, user.Uid, len(items), len(headerLineItems))
|
||||
return nil, nil, nil, nil, errs.ErrFewerFieldsInDataRowThanInHeaderRow
|
||||
return nil, nil, nil, nil, nil, nil, errs.ErrFewerFieldsInDataRowThanInHeaderRow
|
||||
}
|
||||
|
||||
if items[statusColumnIdx] == alipayTransactionDataStatusSuccessName || items[statusColumnIdx] == alipayTransactionDataStatusPaymentSuccessName || items[statusColumnIdx] == alipayTransactionDataStatusRepaymentSuccessName {
|
||||
@@ -145,7 +145,7 @@ func (c *alipayTransactionDataCsvImporter) ParseImportedData(ctx core.Context, u
|
||||
alipayTransactionTypeFundStatusNameMapping,
|
||||
)
|
||||
|
||||
return dataTableImporter.ParseImportedData(ctx, user, dataTable, defaultTimezoneOffset, accountMap, categoryMap, tagMap)
|
||||
return dataTableImporter.ParseImportedData(ctx, user, dataTable, defaultTimezoneOffset, accountMap, expenseCategoryMap, incomeCategoryMap, transferCategoryMap, tagMap)
|
||||
}
|
||||
|
||||
func (c *alipayTransactionDataCsvImporter) parseAllLinesFromCsvData(ctx core.Context, reader io.Reader) ([][]string, error) {
|
||||
|
||||
@@ -34,12 +34,14 @@ func TestAlipayCsvFileImporterParseImportedData_MinimumValidData(t *testing.T) {
|
||||
"------------------------------------------------------------------------------------\n")
|
||||
assert.Nil(t, err)
|
||||
|
||||
allNewTransactions, allNewAccounts, allNewSubCategories, allNewTags, err := converter.ParseImportedData(context, user, []byte(data), 0, nil, nil, nil)
|
||||
allNewTransactions, allNewAccounts, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, allNewTags, err := converter.ParseImportedData(context, user, []byte(data), 0, nil, nil, nil, nil, nil)
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.Equal(t, 3, len(allNewTransactions))
|
||||
assert.Equal(t, 2, len(allNewAccounts))
|
||||
assert.Equal(t, 1, len(allNewSubCategories))
|
||||
assert.Equal(t, 1, len(allNewSubExpenseCategories))
|
||||
assert.Equal(t, 1, len(allNewSubIncomeCategories))
|
||||
assert.Equal(t, 1, len(allNewSubTransferCategories))
|
||||
assert.Equal(t, 0, len(allNewTags))
|
||||
|
||||
assert.Equal(t, int64(1234567890), allNewTransactions[0].Uid)
|
||||
@@ -72,8 +74,14 @@ func TestAlipayCsvFileImporterParseImportedData_MinimumValidData(t *testing.T) {
|
||||
assert.Equal(t, "", allNewAccounts[1].Name)
|
||||
assert.Equal(t, "CNY", allNewAccounts[1].Currency)
|
||||
|
||||
assert.Equal(t, int64(1234567890), allNewSubCategories[0].Uid)
|
||||
assert.Equal(t, "", allNewSubCategories[0].Name)
|
||||
assert.Equal(t, int64(1234567890), allNewSubExpenseCategories[0].Uid)
|
||||
assert.Equal(t, "", allNewSubExpenseCategories[0].Name)
|
||||
|
||||
assert.Equal(t, int64(1234567890), allNewSubIncomeCategories[0].Uid)
|
||||
assert.Equal(t, "", allNewSubIncomeCategories[0].Name)
|
||||
|
||||
assert.Equal(t, int64(1234567890), allNewSubTransferCategories[0].Uid)
|
||||
assert.Equal(t, "", allNewSubTransferCategories[0].Name)
|
||||
}
|
||||
|
||||
func TestAlipayCsvFileImporterParseImportedData_ParseRefundTransaction(t *testing.T) {
|
||||
@@ -94,7 +102,7 @@ func TestAlipayCsvFileImporterParseImportedData_ParseRefundTransaction(t *testin
|
||||
"------------------------------------------------------------------------------------\n")
|
||||
assert.Nil(t, err)
|
||||
|
||||
allNewTransactions, _, _, _, err := converter.ParseImportedData(context, user, []byte(data1), 0, nil, nil, nil)
|
||||
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(data1), 0, nil, nil, nil, nil, nil)
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.Equal(t, int64(1234567890), allNewTransactions[0].Uid)
|
||||
@@ -113,7 +121,7 @@ func TestAlipayCsvFileImporterParseImportedData_ParseRefundTransaction(t *testin
|
||||
"------------------------------------------------------------------------------------\n")
|
||||
assert.Nil(t, err)
|
||||
|
||||
allNewTransactions, _, _, _, err = converter.ParseImportedData(context, user, []byte(data2), 0, nil, nil, nil)
|
||||
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data2), 0, nil, nil, nil, nil, nil)
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.Equal(t, int64(1234567890), allNewTransactions[0].Uid)
|
||||
@@ -142,7 +150,7 @@ func TestAlipayCsvFileImporterParseImportedData_ParseInvalidTime(t *testing.T) {
|
||||
"------------------------------------------------------------------------------------\n")
|
||||
assert.Nil(t, err)
|
||||
|
||||
_, _, _, _, err = converter.ParseImportedData(context, user, []byte(data1), 0, nil, nil, nil)
|
||||
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data1), 0, nil, nil, nil, nil, nil)
|
||||
assert.EqualError(t, err, errs.ErrTransactionTimeInvalid.Message)
|
||||
|
||||
data2, err := simplifiedchinese.GB18030.NewEncoder().String("支付宝交易记录明细查询\n" +
|
||||
@@ -154,7 +162,7 @@ func TestAlipayCsvFileImporterParseImportedData_ParseInvalidTime(t *testing.T) {
|
||||
"------------------------------------------------------------------------------------\n")
|
||||
assert.Nil(t, err)
|
||||
|
||||
_, _, _, _, err = converter.ParseImportedData(context, user, []byte(data2), 0, nil, nil, nil)
|
||||
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data2), 0, nil, nil, nil, nil, nil)
|
||||
assert.EqualError(t, err, errs.ErrTransactionTimeInvalid.Message)
|
||||
}
|
||||
|
||||
@@ -176,7 +184,7 @@ func TestAlipayCsvFileImporterParseImportedData_ParseInvalidType(t *testing.T) {
|
||||
"------------------------------------------------------------------------------------\n")
|
||||
assert.Nil(t, err)
|
||||
|
||||
_, _, _, _, err = converter.ParseImportedData(context, user, []byte(data), 0, nil, nil, nil)
|
||||
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data), 0, nil, nil, nil, nil, nil)
|
||||
assert.EqualError(t, err, errs.ErrNotFoundTransactionDataInFile.Message)
|
||||
}
|
||||
|
||||
@@ -199,7 +207,7 @@ func TestAlipayCsvFileImporterParseImportedData_ParseAccountName(t *testing.T) {
|
||||
"------------------------------------------------------------------------------------\n")
|
||||
assert.Nil(t, err)
|
||||
|
||||
allNewTransactions, _, _, _, err := converter.ParseImportedData(context, user, []byte(data1), 0, nil, nil, nil)
|
||||
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(data1), 0, nil, nil, nil, nil, nil)
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.Equal(t, 1, len(allNewTransactions))
|
||||
@@ -215,7 +223,7 @@ func TestAlipayCsvFileImporterParseImportedData_ParseAccountName(t *testing.T) {
|
||||
"------------------------------------------------------------------------------------\n")
|
||||
assert.Nil(t, err)
|
||||
|
||||
allNewTransactions, _, _, _, err = converter.ParseImportedData(context, user, []byte(data2), 0, nil, nil, nil)
|
||||
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data2), 0, nil, nil, nil, nil, nil)
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.Equal(t, 1, len(allNewTransactions))
|
||||
@@ -231,7 +239,7 @@ func TestAlipayCsvFileImporterParseImportedData_ParseAccountName(t *testing.T) {
|
||||
"------------------------------------------------------------------------------------\n")
|
||||
assert.Nil(t, err)
|
||||
|
||||
allNewTransactions, _, _, _, err = converter.ParseImportedData(context, user, []byte(data3), 0, nil, nil, nil)
|
||||
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data3), 0, nil, nil, nil, nil, nil)
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.Equal(t, 1, len(allNewTransactions))
|
||||
@@ -248,7 +256,7 @@ func TestAlipayCsvFileImporterParseImportedData_ParseAccountName(t *testing.T) {
|
||||
"------------------------------------------------------------------------------------\n")
|
||||
assert.Nil(t, err)
|
||||
|
||||
allNewTransactions, _, _, _, err = converter.ParseImportedData(context, user, []byte(data4), 0, nil, nil, nil)
|
||||
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data4), 0, nil, nil, nil, nil, nil)
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.Equal(t, 1, len(allNewTransactions))
|
||||
@@ -265,7 +273,7 @@ func TestAlipayCsvFileImporterParseImportedData_ParseAccountName(t *testing.T) {
|
||||
"------------------------------------------------------------------------------------\n")
|
||||
assert.Nil(t, err)
|
||||
|
||||
allNewTransactions, _, _, _, err = converter.ParseImportedData(context, user, []byte(data5), 0, nil, nil, nil)
|
||||
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data5), 0, nil, nil, nil, nil, nil)
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.Equal(t, 1, len(allNewTransactions))
|
||||
@@ -282,7 +290,7 @@ func TestAlipayCsvFileImporterParseImportedData_ParseAccountName(t *testing.T) {
|
||||
"------------------------------------------------------------------------------------\n")
|
||||
assert.Nil(t, err)
|
||||
|
||||
allNewTransactions, _, _, _, err = converter.ParseImportedData(context, user, []byte(data6), 0, nil, nil, nil)
|
||||
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data6), 0, nil, nil, nil, nil, nil)
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.Equal(t, 1, len(allNewTransactions))
|
||||
@@ -299,7 +307,7 @@ func TestAlipayCsvFileImporterParseImportedData_ParseAccountName(t *testing.T) {
|
||||
"------------------------------------------------------------------------------------\n")
|
||||
assert.Nil(t, err)
|
||||
|
||||
allNewTransactions, _, _, _, err = converter.ParseImportedData(context, user, []byte(data7), 0, nil, nil, nil)
|
||||
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data7), 0, nil, nil, nil, nil, nil)
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.Equal(t, 1, len(allNewTransactions))
|
||||
@@ -325,7 +333,7 @@ func TestAlipayCsvFileImporterParseImportedData_ParseDescription(t *testing.T) {
|
||||
"------------------------------------------------------------------------------------\n")
|
||||
assert.Nil(t, err)
|
||||
|
||||
allNewTransactions, _, _, _, err := converter.ParseImportedData(context, user, []byte(data1), 0, nil, nil, nil)
|
||||
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(data1), 0, nil, nil, nil, nil, nil)
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.Equal(t, 1, len(allNewTransactions))
|
||||
@@ -340,7 +348,7 @@ func TestAlipayCsvFileImporterParseImportedData_ParseDescription(t *testing.T) {
|
||||
"------------------------------------------------------------------------------------\n")
|
||||
assert.Nil(t, err)
|
||||
|
||||
allNewTransactions, _, _, _, err = converter.ParseImportedData(context, user, []byte(data2), 0, nil, nil, nil)
|
||||
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data2), 0, nil, nil, nil, nil, nil)
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.Equal(t, 1, len(allNewTransactions))
|
||||
@@ -362,10 +370,10 @@ func TestAlipayCsvFileImporterParseImportedData_MissingFileHeader(t *testing.T)
|
||||
"------------------------------------------------------------------------------------\n")
|
||||
assert.Nil(t, err)
|
||||
|
||||
_, _, _, _, err = converter.ParseImportedData(context, user, []byte(data), 0, nil, nil, nil)
|
||||
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data), 0, nil, nil, nil, nil, nil)
|
||||
assert.EqualError(t, err, errs.ErrInvalidFileHeader.Message)
|
||||
|
||||
_, _, _, _, err = converter.ParseImportedData(context, user, []byte(""), 0, nil, nil, nil)
|
||||
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(""), 0, nil, nil, nil, nil, nil)
|
||||
assert.EqualError(t, err, errs.ErrInvalidFileHeader.Message)
|
||||
}
|
||||
|
||||
@@ -386,7 +394,7 @@ func TestAlipayCsvFileImporterParseImportedData_MissingRequiredColumn(t *testing
|
||||
"金额(元),交易状态 ,资金状态 ,\n" +
|
||||
"0.12 ,交易成功 ,已收入 ,\n" +
|
||||
"------------------------------------------------------------------------------------\n")
|
||||
_, _, _, _, err = converter.ParseImportedData(context, user, []byte(data1), 0, nil, nil, nil)
|
||||
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data1), 0, nil, nil, nil, nil, nil)
|
||||
assert.EqualError(t, err, errs.ErrMissingRequiredFieldInHeaderRow.Message)
|
||||
|
||||
// Missing Amount Column
|
||||
@@ -397,7 +405,7 @@ func TestAlipayCsvFileImporterParseImportedData_MissingRequiredColumn(t *testing
|
||||
"交易创建时间 ,交易状态 ,资金状态 ,\n" +
|
||||
"2024-09-01 12:34:56 ,交易成功 ,已收入 ,\n" +
|
||||
"------------------------------------------------------------------------------------\n")
|
||||
_, _, _, _, err = converter.ParseImportedData(context, user, []byte(data2), 0, nil, nil, nil)
|
||||
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data2), 0, nil, nil, nil, nil, nil)
|
||||
assert.EqualError(t, err, errs.ErrMissingRequiredFieldInHeaderRow.Message)
|
||||
|
||||
// Missing Status Column
|
||||
@@ -408,7 +416,7 @@ func TestAlipayCsvFileImporterParseImportedData_MissingRequiredColumn(t *testing
|
||||
"交易创建时间 ,金额(元),资金状态 ,\n" +
|
||||
"2024-09-01 12:34:56 ,0.12 ,已收入 ,\n" +
|
||||
"------------------------------------------------------------------------------------\n")
|
||||
_, _, _, _, err = converter.ParseImportedData(context, user, []byte(data3), 0, nil, nil, nil)
|
||||
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data3), 0, nil, nil, nil, nil, nil)
|
||||
assert.EqualError(t, err, errs.ErrMissingRequiredFieldInHeaderRow.Message)
|
||||
|
||||
// Missing Fund Status Column
|
||||
@@ -419,6 +427,6 @@ func TestAlipayCsvFileImporterParseImportedData_MissingRequiredColumn(t *testing
|
||||
"交易创建时间 ,金额(元),交易状态 ,\n" +
|
||||
"2024-09-01 12:34:56 ,0.12 ,交易成功 ,\n" +
|
||||
"------------------------------------------------------------------------------------\n")
|
||||
_, _, _, _, err = converter.ParseImportedData(context, user, []byte(data4), 0, nil, nil, nil)
|
||||
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data4), 0, nil, nil, nil, nil, nil)
|
||||
assert.EqualError(t, err, errs.ErrMissingRequiredFieldInHeaderRow.Message)
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ type TransactionDataExporter interface {
|
||||
// TransactionDataImporter defines the structure of transaction data importer
|
||||
type TransactionDataImporter interface {
|
||||
// ParseImportedData returns the imported data
|
||||
ParseImportedData(ctx core.Context, user *models.User, data []byte, defaultTimezoneOffset int16, accountMap map[string]*models.Account, categoryMap map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionTag, error)
|
||||
ParseImportedData(ctx core.Context, user *models.User, data []byte, defaultTimezoneOffset int16, accountMap map[string]*models.Account, expenseCategoryMap map[string]*models.TransactionCategory, incomeCategoryMap map[string]*models.TransactionCategory, transferCategoryMap map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionTag, error)
|
||||
}
|
||||
|
||||
// TransactionDataConverter defines the structure of transaction data converter
|
||||
|
||||
@@ -240,16 +240,16 @@ func (c *DataTableTransactionDataExporter) getExportedTags(dataTableBuilder Data
|
||||
}
|
||||
|
||||
// ParseImportedData returns the imported transaction data
|
||||
func (c *DataTableTransactionDataImporter) ParseImportedData(ctx core.Context, user *models.User, dataTable ImportedDataTable, defaultTimezoneOffset int16, accountMap map[string]*models.Account, categoryMap map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionTag, error) {
|
||||
func (c *DataTableTransactionDataImporter) ParseImportedData(ctx core.Context, user *models.User, dataTable ImportedDataTable, defaultTimezoneOffset int16, accountMap map[string]*models.Account, expenseCategoryMap map[string]*models.TransactionCategory, incomeCategoryMap map[string]*models.TransactionCategory, transferCategoryMap map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionTag, error) {
|
||||
if dataTable.DataRowCount() < 1 {
|
||||
log.Errorf(ctx, "[data_table_transaction_data_converter.parseImportedData] cannot parse import data for user \"uid:%d\", because data table row count is less 1", user.Uid)
|
||||
return nil, nil, nil, nil, errs.ErrNotFoundTransactionDataInFile
|
||||
return nil, nil, nil, nil, nil, nil, errs.ErrNotFoundTransactionDataInFile
|
||||
}
|
||||
|
||||
nameDbTypeMap, err := c.buildTransactionTypeNameDbTypeMap()
|
||||
|
||||
if err != nil {
|
||||
return nil, nil, nil, nil, err
|
||||
return nil, nil, nil, nil, nil, nil, err
|
||||
}
|
||||
|
||||
headerLineItems := dataTable.HeaderLineColumnNames()
|
||||
@@ -276,15 +276,23 @@ func (c *DataTableTransactionDataImporter) ParseImportedData(ctx core.Context, u
|
||||
if !timeColumnExists || !typeColumnExists || !subCategoryColumnExists ||
|
||||
!accountColumnExists || !amountColumnExists || !account2ColumnExists {
|
||||
log.Errorf(ctx, "[data_table_transaction_data_converter.parseImportedData] cannot parse import data for user \"uid:%d\", because missing essential columns in header row", user.Uid)
|
||||
return nil, nil, nil, nil, errs.ErrMissingRequiredFieldInHeaderRow
|
||||
return nil, nil, nil, nil, nil, nil, errs.ErrMissingRequiredFieldInHeaderRow
|
||||
}
|
||||
|
||||
if accountMap == nil {
|
||||
accountMap = make(map[string]*models.Account)
|
||||
}
|
||||
|
||||
if categoryMap == nil {
|
||||
categoryMap = make(map[string]*models.TransactionCategory)
|
||||
if expenseCategoryMap == nil {
|
||||
expenseCategoryMap = make(map[string]*models.TransactionCategory)
|
||||
}
|
||||
|
||||
if incomeCategoryMap == nil {
|
||||
incomeCategoryMap = make(map[string]*models.TransactionCategory)
|
||||
}
|
||||
|
||||
if transferCategoryMap == nil {
|
||||
transferCategoryMap = make(map[string]*models.TransactionCategory)
|
||||
}
|
||||
|
||||
if tagMap == nil {
|
||||
@@ -293,7 +301,9 @@ func (c *DataTableTransactionDataImporter) ParseImportedData(ctx core.Context, u
|
||||
|
||||
allNewTransactions := make(models.ImportedTransactionSlice, 0, dataTable.DataRowCount())
|
||||
allNewAccounts := make([]*models.Account, 0)
|
||||
allNewSubCategories := make([]*models.TransactionCategory, 0)
|
||||
allNewSubExpenseCategories := make([]*models.TransactionCategory, 0)
|
||||
allNewSubIncomeCategories := make([]*models.TransactionCategory, 0)
|
||||
allNewSubTransferCategories := make([]*models.TransactionCategory, 0)
|
||||
allNewTags := make([]*models.TransactionTag, 0)
|
||||
|
||||
dataRowIterator := dataTable.DataRowIterator()
|
||||
@@ -310,7 +320,7 @@ func (c *DataTableTransactionDataImporter) ParseImportedData(ctx core.Context, u
|
||||
|
||||
if columnCount < len(headerLineItems) {
|
||||
log.Errorf(ctx, "[data_table_transaction_data_converter.parseImportedData] cannot parse data row \"index:%d\" for user \"uid:%d\", because may missing some columns (column count %d in data row is less than header column count %d)", dataRowIndex, user.Uid, columnCount, len(headerLineItems))
|
||||
return nil, nil, nil, nil, errs.ErrFewerFieldsInDataRowThanInHeaderRow
|
||||
return nil, nil, nil, nil, nil, nil, errs.ErrFewerFieldsInDataRowThanInHeaderRow
|
||||
}
|
||||
|
||||
timezoneOffset := defaultTimezoneOffset
|
||||
@@ -320,7 +330,7 @@ func (c *DataTableTransactionDataImporter) ParseImportedData(ctx core.Context, u
|
||||
|
||||
if err != nil {
|
||||
log.Errorf(ctx, "[data_table_transaction_data_converter.parseImportedData] cannot parse time zone \"%s\" in data row \"index:%d\" for user \"uid:%d\", because %s", dataRow.GetData(timezoneColumnIdx), dataRowIndex, user.Uid, err.Error())
|
||||
return nil, nil, nil, nil, errs.ErrTransactionTimeZoneInvalid
|
||||
return nil, nil, nil, nil, nil, nil, errs.ErrTransactionTimeZoneInvalid
|
||||
}
|
||||
|
||||
timezoneOffset = utils.GetTimezoneOffsetMinutes(transactionTimezone)
|
||||
@@ -330,14 +340,14 @@ func (c *DataTableTransactionDataImporter) ParseImportedData(ctx core.Context, u
|
||||
|
||||
if err != nil {
|
||||
log.Errorf(ctx, "[data_table_transaction_data_converter.parseImportedData] cannot parse time \"%s\" in data row \"index:%d\" for user \"uid:%d\", because %s", dataRow.GetData(timeColumnIdx), dataRowIndex, user.Uid, err.Error())
|
||||
return nil, nil, nil, nil, errs.ErrTransactionTimeInvalid
|
||||
return nil, nil, nil, nil, nil, nil, errs.ErrTransactionTimeInvalid
|
||||
}
|
||||
|
||||
transactionDbType, err := c.getTransactionDbType(nameDbTypeMap, dataRow.GetData(typeColumnIdx))
|
||||
|
||||
if err != nil {
|
||||
log.Errorf(ctx, "[data_table_transaction_data_converter.parseImportedData] cannot parse transaction type \"%s\" in data row \"index:%d\" for user \"uid:%d\", because %s", dataRow.GetData(typeColumnIdx), dataRowIndex, user.Uid, err.Error())
|
||||
return nil, nil, nil, nil, errs.Or(err, errs.ErrTransactionTypeInvalid)
|
||||
return nil, nil, nil, nil, nil, nil, errs.Or(err, errs.ErrTransactionTypeInvalid)
|
||||
}
|
||||
|
||||
categoryId := int64(0)
|
||||
@@ -348,19 +358,42 @@ func (c *DataTableTransactionDataImporter) ParseImportedData(ctx core.Context, u
|
||||
|
||||
if err != nil {
|
||||
log.Errorf(ctx, "[data_table_transaction_data_converter.parseImportedData] cannot parse transaction category type in data row \"index:%d\" for user \"uid:%d\", because %s", dataRowIndex, user.Uid, err.Error())
|
||||
return nil, nil, nil, nil, errs.Or(err, errs.ErrTransactionTypeInvalid)
|
||||
return nil, nil, nil, nil, nil, nil, errs.Or(err, errs.ErrTransactionTypeInvalid)
|
||||
}
|
||||
|
||||
subCategoryName = dataRow.GetData(subCategoryColumnIdx)
|
||||
subCategory, exists := categoryMap[subCategoryName]
|
||||
|
||||
if transactionDbType == models.TRANSACTION_DB_TYPE_EXPENSE {
|
||||
subCategory, exists := expenseCategoryMap[subCategoryName]
|
||||
|
||||
if !exists {
|
||||
subCategory = c.createNewTransactionCategoryModel(user.Uid, subCategoryName, transactionCategoryType)
|
||||
allNewSubCategories = append(allNewSubCategories, subCategory)
|
||||
categoryMap[subCategoryName] = subCategory
|
||||
allNewSubExpenseCategories = append(allNewSubExpenseCategories, subCategory)
|
||||
expenseCategoryMap[subCategoryName] = subCategory
|
||||
}
|
||||
|
||||
categoryId = subCategory.CategoryId
|
||||
} else if transactionDbType == models.TRANSACTION_DB_TYPE_INCOME {
|
||||
subCategory, exists := incomeCategoryMap[subCategoryName]
|
||||
|
||||
if !exists {
|
||||
subCategory = c.createNewTransactionCategoryModel(user.Uid, subCategoryName, transactionCategoryType)
|
||||
allNewSubIncomeCategories = append(allNewSubIncomeCategories, subCategory)
|
||||
incomeCategoryMap[subCategoryName] = subCategory
|
||||
}
|
||||
|
||||
categoryId = subCategory.CategoryId
|
||||
} else if transactionDbType == models.TRANSACTION_DB_TYPE_TRANSFER_OUT {
|
||||
subCategory, exists := transferCategoryMap[subCategoryName]
|
||||
|
||||
if !exists {
|
||||
subCategory = c.createNewTransactionCategoryModel(user.Uid, subCategoryName, transactionCategoryType)
|
||||
allNewSubTransferCategories = append(allNewSubTransferCategories, subCategory)
|
||||
transferCategoryMap[subCategoryName] = subCategory
|
||||
}
|
||||
|
||||
categoryId = subCategory.CategoryId
|
||||
}
|
||||
}
|
||||
|
||||
accountName := dataRow.GetData(accountColumnIdx)
|
||||
@@ -371,7 +404,7 @@ func (c *DataTableTransactionDataImporter) ParseImportedData(ctx core.Context, u
|
||||
|
||||
if _, ok := validators.AllCurrencyNames[accountCurrency]; !ok {
|
||||
log.Errorf(ctx, "[data_table_transaction_data_converter.parseImportedData] account currency \"%s\" is not supported in data row \"index:%d\" for user \"uid:%d\"", accountCurrency, dataRowIndex, user.Uid)
|
||||
return nil, nil, nil, nil, errs.ErrAccountCurrencyInvalid
|
||||
return nil, nil, nil, nil, nil, nil, errs.ErrAccountCurrencyInvalid
|
||||
}
|
||||
}
|
||||
|
||||
@@ -386,7 +419,7 @@ func (c *DataTableTransactionDataImporter) ParseImportedData(ctx core.Context, u
|
||||
if accountCurrencyColumnExists {
|
||||
if account.Name != "" && account.Currency != accountCurrency {
|
||||
log.Errorf(ctx, "[data_table_transaction_data_converter.parseImportedData] currency \"%s\" in data row \"index:%d\" not equals currency \"%s\" of the account for user \"uid:%d\"", accountCurrency, dataRowIndex, account.Currency, user.Uid)
|
||||
return nil, nil, nil, nil, errs.ErrAccountCurrencyInvalid
|
||||
return nil, nil, nil, nil, nil, nil, errs.ErrAccountCurrencyInvalid
|
||||
}
|
||||
} else if exists {
|
||||
accountCurrency = account.Currency
|
||||
@@ -396,7 +429,7 @@ func (c *DataTableTransactionDataImporter) ParseImportedData(ctx core.Context, u
|
||||
|
||||
if err != nil {
|
||||
log.Errorf(ctx, "[data_table_transaction_data_converter.parseImportedData] cannot parse acmount \"%s\" in data row \"index:%d\" for user \"uid:%d\", because %s", dataRow.GetData(amountColumnIdx), dataRowIndex, user.Uid, err.Error())
|
||||
return nil, nil, nil, nil, errs.ErrAmountInvalid
|
||||
return nil, nil, nil, nil, nil, nil, errs.ErrAmountInvalid
|
||||
}
|
||||
|
||||
relatedAccountId := int64(0)
|
||||
@@ -413,7 +446,7 @@ func (c *DataTableTransactionDataImporter) ParseImportedData(ctx core.Context, u
|
||||
|
||||
if _, ok := validators.AllCurrencyNames[account2Currency]; !ok {
|
||||
log.Errorf(ctx, "[data_table_transaction_data_converter.parseImportedData] account2 currency \"%s\" is not supported in data row \"index:%d\" for user \"uid:%d\"", account2Currency, dataRowIndex, user.Uid)
|
||||
return nil, nil, nil, nil, errs.ErrAccountCurrencyInvalid
|
||||
return nil, nil, nil, nil, nil, nil, errs.ErrAccountCurrencyInvalid
|
||||
}
|
||||
}
|
||||
|
||||
@@ -428,7 +461,7 @@ func (c *DataTableTransactionDataImporter) ParseImportedData(ctx core.Context, u
|
||||
if account2CurrencyColumnExists {
|
||||
if account2.Name != "" && account2.Currency != account2Currency {
|
||||
log.Errorf(ctx, "[data_table_transaction_data_converter.parseImportedData] currency \"%s\" in data row \"index:%d\" not equals currency \"%s\" of the account2 for user \"uid:%d\"", account2Currency, dataRowIndex, account2.Currency, user.Uid)
|
||||
return nil, nil, nil, nil, errs.ErrAccountCurrencyInvalid
|
||||
return nil, nil, nil, nil, nil, nil, errs.ErrAccountCurrencyInvalid
|
||||
}
|
||||
} else if exists {
|
||||
account2Currency = account2.Currency
|
||||
@@ -441,7 +474,7 @@ func (c *DataTableTransactionDataImporter) ParseImportedData(ctx core.Context, u
|
||||
|
||||
if err != nil {
|
||||
log.Errorf(ctx, "[data_table_transaction_data_converter.parseImportedData] cannot parse acmount2 \"%s\" in data row \"index:%d\" for user \"uid:%d\", because %s", dataRow.GetData(amount2ColumnIdx), dataRowIndex, user.Uid, err.Error())
|
||||
return nil, nil, nil, nil, errs.ErrAmountInvalid
|
||||
return nil, nil, nil, nil, nil, nil, errs.ErrAmountInvalid
|
||||
}
|
||||
} else if transactionDbType == models.TRANSACTION_DB_TYPE_TRANSFER_OUT {
|
||||
relatedAccountAmount = amount
|
||||
@@ -459,14 +492,14 @@ func (c *DataTableTransactionDataImporter) ParseImportedData(ctx core.Context, u
|
||||
|
||||
if err != nil {
|
||||
log.Errorf(ctx, "[data_table_transaction_data_converter.parseImportedData] cannot parse geographic location \"%s\" in data row \"index:%d\" for user \"uid:%d\", because %s", dataRow.GetData(geoLocationIdx), dataRowIndex, user.Uid, err.Error())
|
||||
return nil, nil, nil, nil, errs.ErrGeographicLocationInvalid
|
||||
return nil, nil, nil, nil, nil, nil, errs.ErrGeographicLocationInvalid
|
||||
}
|
||||
|
||||
geoLatitude, err = utils.StringToFloat64(geoLocationItems[1])
|
||||
|
||||
if err != nil {
|
||||
log.Errorf(ctx, "[data_table_transaction_data_converter.parseImportedData] cannot parse geographic location \"%s\" in data row \"index:%d\" for user \"uid:%d\", because %s", dataRow.GetData(geoLocationIdx), dataRowIndex, user.Uid, err.Error())
|
||||
return nil, nil, nil, nil, errs.ErrGeographicLocationInvalid
|
||||
return nil, nil, nil, nil, nil, nil, errs.ErrGeographicLocationInvalid
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -537,7 +570,7 @@ func (c *DataTableTransactionDataImporter) ParseImportedData(ctx core.Context, u
|
||||
|
||||
if err != nil {
|
||||
log.Errorf(ctx, "[data_table_transaction_data_converter.parseImportedData] cannot post process data row \"index:%d\" for user \"uid:%d\", because %s", dataRowIndex, user.Uid, err.Error())
|
||||
return nil, nil, nil, nil, err
|
||||
return nil, nil, nil, nil, nil, nil, err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -546,7 +579,7 @@ func (c *DataTableTransactionDataImporter) ParseImportedData(ctx core.Context, u
|
||||
|
||||
sort.Sort(allNewTransactions)
|
||||
|
||||
return allNewTransactions, allNewAccounts, allNewSubCategories, allNewTags, nil
|
||||
return allNewTransactions, allNewAccounts, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, allNewTags, nil
|
||||
}
|
||||
|
||||
func (c *DataTableTransactionDataImporter) buildTransactionTypeNameDbTypeMap() (map[string]models.TransactionDbType, error) {
|
||||
|
||||
@@ -83,7 +83,7 @@ func (c *ezBookKeepingTransactionDataPlainTextConverter) ToExportedContent(ctx c
|
||||
}
|
||||
|
||||
// ParseImportedData returns the imported data by parsing the transaction plain text data
|
||||
func (c *ezBookKeepingTransactionDataPlainTextConverter) ParseImportedData(ctx core.Context, user *models.User, data []byte, defaultTimezoneOffset int16, accountMap map[string]*models.Account, categoryMap map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionTag, error) {
|
||||
func (c *ezBookKeepingTransactionDataPlainTextConverter) ParseImportedData(ctx core.Context, user *models.User, data []byte, defaultTimezoneOffset int16, accountMap map[string]*models.Account, expenseCategoryMap map[string]*models.TransactionCategory, incomeCategoryMap map[string]*models.TransactionCategory, transferCategoryMap map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionTag, error) {
|
||||
dataTable, err := createNewezbookkeepingTransactionPlainTextDataTable(
|
||||
string(data),
|
||||
c.columnSeparator,
|
||||
@@ -91,7 +91,7 @@ func (c *ezBookKeepingTransactionDataPlainTextConverter) ParseImportedData(ctx c
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, nil, nil, nil, err
|
||||
return nil, nil, nil, nil, nil, nil, err
|
||||
}
|
||||
|
||||
dataTableImporter := datatable.CreateNewImporter(
|
||||
@@ -101,5 +101,5 @@ func (c *ezBookKeepingTransactionDataPlainTextConverter) ParseImportedData(ctx c
|
||||
ezbookkeepingTagSeparator,
|
||||
)
|
||||
|
||||
return dataTableImporter.ParseImportedData(ctx, user, dataTable, defaultTimezoneOffset, accountMap, categoryMap, tagMap)
|
||||
return dataTableImporter.ParseImportedData(ctx, user, dataTable, defaultTimezoneOffset, accountMap, expenseCategoryMap, incomeCategoryMap, transferCategoryMap, tagMap)
|
||||
}
|
||||
|
||||
+64
-62
@@ -134,17 +134,19 @@ func TestEzBookKeepingPlainFileConverterParseImportedData_MinimumValidData(t *te
|
||||
DefaultCurrency: "CNY",
|
||||
}
|
||||
|
||||
allNewTransactions, allNewAccounts, allNewSubCategories, allNewTags, err := converter.ParseImportedData(context, user, []byte("Time,Type,Sub Category,Account,Amount,Account2,Account2 Amount\n"+
|
||||
allNewTransactions, allNewAccounts, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, allNewTags, err := converter.ParseImportedData(context, user, []byte("Time,Type,Sub Category,Account,Amount,Account2,Account2 Amount\n"+
|
||||
"2024-09-01 00:00:00,Balance Modification,,Test Account,123.45,,\n"+
|
||||
"2024-09-01 01:23:45,Income,Test Category,Test Account,0.12,,\n"+
|
||||
"2024-09-01 12:34:56,Expense,Test Category2,Test Account,1.00,,\n"+
|
||||
"2024-09-01 23:59:59,Transfer,Test Category3,Test Account,0.05,Test Account2,0.05"), 0, nil, nil, nil)
|
||||
"2024-09-01 23:59:59,Transfer,Test Category3,Test Account,0.05,Test Account2,0.05"), 0, nil, nil, nil, nil, nil)
|
||||
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.Equal(t, 4, len(allNewTransactions))
|
||||
assert.Equal(t, 2, len(allNewAccounts))
|
||||
assert.Equal(t, 3, len(allNewSubCategories))
|
||||
assert.Equal(t, 1, len(allNewSubExpenseCategories))
|
||||
assert.Equal(t, 1, len(allNewSubIncomeCategories))
|
||||
assert.Equal(t, 1, len(allNewSubTransferCategories))
|
||||
assert.Equal(t, 0, len(allNewTags))
|
||||
|
||||
assert.Equal(t, int64(1234567890), allNewTransactions[0].Uid)
|
||||
@@ -184,14 +186,14 @@ func TestEzBookKeepingPlainFileConverterParseImportedData_MinimumValidData(t *te
|
||||
assert.Equal(t, "Test Account2", allNewAccounts[1].Name)
|
||||
assert.Equal(t, "CNY", allNewAccounts[1].Currency)
|
||||
|
||||
assert.Equal(t, int64(1234567890), allNewSubCategories[0].Uid)
|
||||
assert.Equal(t, "Test Category", allNewSubCategories[0].Name)
|
||||
assert.Equal(t, int64(1234567890), allNewSubExpenseCategories[0].Uid)
|
||||
assert.Equal(t, "Test Category2", allNewSubExpenseCategories[0].Name)
|
||||
|
||||
assert.Equal(t, int64(1234567890), allNewSubCategories[1].Uid)
|
||||
assert.Equal(t, "Test Category2", allNewSubCategories[1].Name)
|
||||
assert.Equal(t, int64(1234567890), allNewSubIncomeCategories[0].Uid)
|
||||
assert.Equal(t, "Test Category", allNewSubIncomeCategories[0].Name)
|
||||
|
||||
assert.Equal(t, int64(1234567890), allNewSubCategories[2].Uid)
|
||||
assert.Equal(t, "Test Category3", allNewSubCategories[2].Name)
|
||||
assert.Equal(t, int64(1234567890), allNewSubTransferCategories[0].Uid)
|
||||
assert.Equal(t, "Test Category3", allNewSubTransferCategories[0].Name)
|
||||
}
|
||||
|
||||
func TestEzBookKeepingPlainFileConverterParseImportedData_ParseInvalidTime(t *testing.T) {
|
||||
@@ -203,12 +205,12 @@ func TestEzBookKeepingPlainFileConverterParseImportedData_ParseInvalidTime(t *te
|
||||
DefaultCurrency: "CNY",
|
||||
}
|
||||
|
||||
_, _, _, _, err := converter.ParseImportedData(context, user, []byte("Time,Type,Sub Category,Account,Amount,Account2,Account2 Amount\n"+
|
||||
"2024-09-01T12:34:56,Expense,Test Category,Test Account,123.45,,"), 0, nil, nil, nil)
|
||||
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte("Time,Type,Sub Category,Account,Amount,Account2,Account2 Amount\n"+
|
||||
"2024-09-01T12:34:56,Expense,Test Category,Test Account,123.45,,"), 0, nil, nil, nil, nil, nil)
|
||||
assert.EqualError(t, err, errs.ErrTransactionTimeInvalid.Message)
|
||||
|
||||
_, _, _, _, err = converter.ParseImportedData(context, user, []byte("Time,Type,Sub Category,Account,Amount,Account2,Account2 Amount\n"+
|
||||
"09/01/2024 12:34:56,Expense,Test Category,Test Account,123.45,,"), 0, nil, nil, nil)
|
||||
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte("Time,Type,Sub Category,Account,Amount,Account2,Account2 Amount\n"+
|
||||
"09/01/2024 12:34:56,Expense,Test Category,Test Account,123.45,,"), 0, nil, nil, nil, nil, nil)
|
||||
assert.EqualError(t, err, errs.ErrTransactionTimeInvalid.Message)
|
||||
}
|
||||
|
||||
@@ -221,8 +223,8 @@ func TestEzBookKeepingPlainFileConverterParseImportedData_ParseInvalidType(t *te
|
||||
DefaultCurrency: "CNY",
|
||||
}
|
||||
|
||||
_, _, _, _, err := converter.ParseImportedData(context, user, []byte("Time,Type,Sub Category,Account,Amount,Account2,Account2 Amount\n"+
|
||||
"2024-09-01 12:34:56,Type,Test Category,Test Account,123.45,,"), 0, nil, nil, nil)
|
||||
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte("Time,Type,Sub Category,Account,Amount,Account2,Account2 Amount\n"+
|
||||
"2024-09-01 12:34:56,Type,Test Category,Test Account,123.45,,"), 0, nil, nil, nil, nil, nil)
|
||||
assert.EqualError(t, err, errs.ErrTransactionTypeInvalid.Message)
|
||||
}
|
||||
|
||||
@@ -235,8 +237,8 @@ func TestEzBookKeepingPlainFileConverterParseImportedData_ParseValidTimezone(t *
|
||||
DefaultCurrency: "CNY",
|
||||
}
|
||||
|
||||
allNewTransactions, _, _, _, err := converter.ParseImportedData(context, user, []byte("Time,Timezone,Type,Sub Category,Account,Amount,Account2,Account2 Amount\n"+
|
||||
"2024-09-01 12:34:56,+08:00,Expense,Test Category,Test Account,123.45,,"), 0, nil, nil, nil)
|
||||
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte("Time,Timezone,Type,Sub Category,Account,Amount,Account2,Account2 Amount\n"+
|
||||
"2024-09-01 12:34:56,+08:00,Expense,Test Category,Test Account,123.45,,"), 0, nil, nil, nil, nil, nil)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 1, len(allNewTransactions))
|
||||
assert.Equal(t, int64(1725165296), utils.GetUnixTimeFromTransactionTime(allNewTransactions[0].TransactionTime))
|
||||
@@ -251,8 +253,8 @@ func TestEzBookKeepingPlainFileConverterParseImportedData_ParseInvalidTimezone(t
|
||||
DefaultCurrency: "CNY",
|
||||
}
|
||||
|
||||
_, _, _, _, err := converter.ParseImportedData(context, user, []byte("Time,Timezone,Type,Sub Category,Account,Amount,Account2,Account2 Amount\n"+
|
||||
"2024-09-01 12:34:56,Asia/Shanghai,Expense,Test Category,Test Account,123.45,,"), 0, nil, nil, nil)
|
||||
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte("Time,Timezone,Type,Sub Category,Account,Amount,Account2,Account2 Amount\n"+
|
||||
"2024-09-01 12:34:56,Asia/Shanghai,Expense,Test Category,Test Account,123.45,,"), 0, nil, nil, nil, nil, nil)
|
||||
assert.EqualError(t, err, errs.ErrTransactionTimeZoneInvalid.Message)
|
||||
}
|
||||
|
||||
@@ -265,9 +267,9 @@ func TestEzBookKeepingPlainFileConverterParseImportedData_ParseValidAccountCurre
|
||||
DefaultCurrency: "CNY",
|
||||
}
|
||||
|
||||
allNewTransactions, allNewAccounts, _, _, err := converter.ParseImportedData(context, user, []byte("Time,Type,Sub Category,Account,Account Currency,Amount,Account2,Account2 Currency,Account2 Amount\n"+
|
||||
allNewTransactions, allNewAccounts, _, _, _, _, err := converter.ParseImportedData(context, user, []byte("Time,Type,Sub Category,Account,Account Currency,Amount,Account2,Account2 Currency,Account2 Amount\n"+
|
||||
"2024-09-01 01:23:45,Balance Modification,,Test Account,USD,123.45,,,\n"+
|
||||
"2024-09-01 12:34:56,Transfer,Test Category2,Test Account,USD,1.23,Test Account2,EUR,1.10"), 0, nil, nil, nil)
|
||||
"2024-09-01 12:34:56,Transfer,Test Category2,Test Account,USD,1.23,Test Account2,EUR,1.10"), 0, nil, nil, nil, nil, nil)
|
||||
|
||||
assert.Nil(t, err)
|
||||
|
||||
@@ -292,14 +294,14 @@ func TestEzBookKeepingPlainFileConverterParseImportedData_ParseInvalidAccountCur
|
||||
DefaultCurrency: "CNY",
|
||||
}
|
||||
|
||||
_, _, _, _, err := converter.ParseImportedData(context, user, []byte("Time,Type,Sub Category,Account,Account Currency,Amount,Account2,Account2 Currency,Account2 Amount\n"+
|
||||
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte("Time,Type,Sub Category,Account,Account Currency,Amount,Account2,Account2 Currency,Account2 Amount\n"+
|
||||
"2024-09-01 01:23:45,Balance Modification,,Test Account,USD,123.45,,,\n"+
|
||||
"2024-09-01 12:34:56,Transfer,Test Category3,Test Account,CNY,1.23,Test Account2,EUR,1.10"), 0, nil, nil, nil)
|
||||
"2024-09-01 12:34:56,Transfer,Test Category3,Test Account,CNY,1.23,Test Account2,EUR,1.10"), 0, nil, nil, nil, nil, nil)
|
||||
assert.EqualError(t, err, errs.ErrAccountCurrencyInvalid.Message)
|
||||
|
||||
_, _, _, _, err = converter.ParseImportedData(context, user, []byte("Time,Type,Sub Category,Account,Account Currency,Amount,Account2,Account2 Currency,Account2 Amount\n"+
|
||||
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte("Time,Type,Sub Category,Account,Account Currency,Amount,Account2,Account2 Currency,Account2 Amount\n"+
|
||||
"2024-09-01 01:23:45,Balance Modification,,Test Account,USD,123.45,,,\n"+
|
||||
"2024-09-01 12:34:56,Transfer,Test Category3,Test Account2,CNY,1.23,Test Account,EUR,1.10"), 0, nil, nil, nil)
|
||||
"2024-09-01 12:34:56,Transfer,Test Category3,Test Account2,CNY,1.23,Test Account,EUR,1.10"), 0, nil, nil, nil, nil, nil)
|
||||
assert.EqualError(t, err, errs.ErrAccountCurrencyInvalid.Message)
|
||||
}
|
||||
|
||||
@@ -312,12 +314,12 @@ func TestEzBookKeepingPlainFileConverterParseImportedData_ParseNotSupportedCurre
|
||||
DefaultCurrency: "CNY",
|
||||
}
|
||||
|
||||
_, _, _, _, err := converter.ParseImportedData(context, user, []byte("Time,Type,Sub Category,Account,Account Currency,Amount,Account2,Account2 Currency,Account2 Amount\n"+
|
||||
"2024-09-01 01:23:45,Balance Modification,,Test Account,XXX,123.45,,,"), 0, nil, nil, nil)
|
||||
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte("Time,Type,Sub Category,Account,Account Currency,Amount,Account2,Account2 Currency,Account2 Amount\n"+
|
||||
"2024-09-01 01:23:45,Balance Modification,,Test Account,XXX,123.45,,,"), 0, nil, nil, nil, nil, nil)
|
||||
assert.EqualError(t, err, errs.ErrAccountCurrencyInvalid.Message)
|
||||
|
||||
_, _, _, _, err = converter.ParseImportedData(context, user, []byte("Time,Type,Sub Category,Account,Account Currency,Amount,Account2,Account2 Currency,Account2 Amount\n"+
|
||||
"2024-09-01 01:23:45,Transfer,Test Category,Test Account,USD,123.45,Test Account2,XXX,123.45"), 0, nil, nil, nil)
|
||||
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte("Time,Type,Sub Category,Account,Account Currency,Amount,Account2,Account2 Currency,Account2 Amount\n"+
|
||||
"2024-09-01 01:23:45,Transfer,Test Category,Test Account,USD,123.45,Test Account2,XXX,123.45"), 0, nil, nil, nil, nil, nil)
|
||||
assert.EqualError(t, err, errs.ErrAccountCurrencyInvalid.Message)
|
||||
}
|
||||
|
||||
@@ -330,12 +332,12 @@ func TestEzBookKeepingPlainFileConverterParseImportedData_ParseInvalidAmount(t *
|
||||
DefaultCurrency: "CNY",
|
||||
}
|
||||
|
||||
_, _, _, _, err := converter.ParseImportedData(context, user, []byte("Time,Type,Sub Category,Account,Amount,Account2,Account2 Amount\n"+
|
||||
"2024-09-01 12:34:56,Expense,Test Category,Test Account,123 45,,"), 0, nil, nil, nil)
|
||||
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte("Time,Type,Sub Category,Account,Amount,Account2,Account2 Amount\n"+
|
||||
"2024-09-01 12:34:56,Expense,Test Category,Test Account,123 45,,"), 0, nil, nil, nil, nil, nil)
|
||||
assert.EqualError(t, err, errs.ErrAmountInvalid.Message)
|
||||
|
||||
_, _, _, _, err = converter.ParseImportedData(context, user, []byte("Time,Type,Sub Category,Account,Amount,Account2,Account2 Amount\n"+
|
||||
"2024-09-01 12:34:56,Transfer,Test Category,Test Account,123.45,Test Account2,123 45"), 0, nil, nil, nil)
|
||||
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte("Time,Type,Sub Category,Account,Amount,Account2,Account2 Amount\n"+
|
||||
"2024-09-01 12:34:56,Transfer,Test Category,Test Account,123.45,Test Account2,123 45"), 0, nil, nil, nil, nil, nil)
|
||||
assert.EqualError(t, err, errs.ErrAmountInvalid.Message)
|
||||
}
|
||||
|
||||
@@ -348,15 +350,15 @@ func TestEzBookKeepingPlainFileConverterParseImportedData_ParseNoAmount2(t *test
|
||||
DefaultCurrency: "CNY",
|
||||
}
|
||||
|
||||
allNewTransactions, _, _, _, err := converter.ParseImportedData(context, user, []byte("Time,Type,Sub Category,Account,Amount,Account2\n"+
|
||||
"2024-09-01 12:34:56,Expense,Test Category,Test Account,123.45,"), 0, nil, nil, nil)
|
||||
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte("Time,Type,Sub Category,Account,Amount,Account2\n"+
|
||||
"2024-09-01 12:34:56,Expense,Test Category,Test Account,123.45,"), 0, nil, nil, nil, nil, nil)
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, int64(12345), allNewTransactions[0].Amount)
|
||||
assert.Equal(t, int64(0), allNewTransactions[0].RelatedAccountAmount)
|
||||
|
||||
allNewTransactions, _, _, _, err = converter.ParseImportedData(context, user, []byte("Time,Type,Sub Category,Account,Amount,Account2\n"+
|
||||
"2024-09-01 12:34:56,Transfer,Test Category,Test Account,123.45,Test Account2"), 0, nil, nil, nil)
|
||||
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte("Time,Type,Sub Category,Account,Amount,Account2\n"+
|
||||
"2024-09-01 12:34:56,Transfer,Test Category,Test Account,123.45,Test Account2"), 0, nil, nil, nil, nil, nil)
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, int64(12345), allNewTransactions[0].Amount)
|
||||
@@ -372,8 +374,8 @@ func TestEzBookKeepingPlainFileConverterParseImportedData_ParseValidGeographicLo
|
||||
DefaultCurrency: "CNY",
|
||||
}
|
||||
|
||||
allNewTransactions, _, _, _, err := converter.ParseImportedData(context, user, []byte("Time,Type,Sub Category,Account,Amount,Account2,Account2 Amount,Geographic Location\n"+
|
||||
"2024-09-01 12:34:56,Expense,Test Category,Test Account,123.45,,,123.45 45.56"), 0, nil, nil, nil)
|
||||
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte("Time,Type,Sub Category,Account,Amount,Account2,Account2 Amount,Geographic Location\n"+
|
||||
"2024-09-01 12:34:56,Expense,Test Category,Test Account,123.45,,,123.45 45.56"), 0, nil, nil, nil, nil, nil)
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 1, len(allNewTransactions))
|
||||
@@ -390,19 +392,19 @@ func TestEzBookKeepingPlainFileConverterParseImportedData_ParseInvalidGeographic
|
||||
DefaultCurrency: "CNY",
|
||||
}
|
||||
|
||||
allNewTransactions, _, _, _, err := converter.ParseImportedData(context, user, []byte("Time,Type,Sub Category,Account,Amount,Account2,Account2 Amount,Geographic Location\n"+
|
||||
"2024-09-01 12:34:56,Expense,Test Category,Test Account,123.45,,,1"), 0, nil, nil, nil)
|
||||
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte("Time,Type,Sub Category,Account,Amount,Account2,Account2 Amount,Geographic Location\n"+
|
||||
"2024-09-01 12:34:56,Expense,Test Category,Test Account,123.45,,,1"), 0, nil, nil, nil, nil, nil)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 1, len(allNewTransactions))
|
||||
assert.Equal(t, float64(0), allNewTransactions[0].GeoLongitude)
|
||||
assert.Equal(t, float64(0), allNewTransactions[0].GeoLatitude)
|
||||
|
||||
_, _, _, _, err = converter.ParseImportedData(context, user, []byte("Time,Type,Sub Category,Account,Amount,Account2,Account2 Amount,Geographic Location\n"+
|
||||
"2024-09-01 12:34:56,Expense,Test Category,Test Account,123.45,,,a b"), 0, nil, nil, nil)
|
||||
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte("Time,Type,Sub Category,Account,Amount,Account2,Account2 Amount,Geographic Location\n"+
|
||||
"2024-09-01 12:34:56,Expense,Test Category,Test Account,123.45,,,a b"), 0, nil, nil, nil, nil, nil)
|
||||
assert.EqualError(t, err, errs.ErrGeographicLocationInvalid.Message)
|
||||
|
||||
_, _, _, _, err = converter.ParseImportedData(context, user, []byte("Time,Type,Sub Category,Account,Amount,Account2,Account2 Amount,Geographic Location\n"+
|
||||
"2024-09-01 12:34:56,Expense,Test Category,Test Account,123.45,,,1 "), 0, nil, nil, nil)
|
||||
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte("Time,Type,Sub Category,Account,Amount,Account2,Account2 Amount,Geographic Location\n"+
|
||||
"2024-09-01 12:34:56,Expense,Test Category,Test Account,123.45,,,1 "), 0, nil, nil, nil, nil, nil)
|
||||
assert.EqualError(t, err, errs.ErrGeographicLocationInvalid.Message)
|
||||
}
|
||||
|
||||
@@ -415,8 +417,8 @@ func TestEzBookKeepingPlainFileConverterParseImportedData_ParseTag(t *testing.T)
|
||||
DefaultCurrency: "CNY",
|
||||
}
|
||||
|
||||
_, _, _, allNewTags, err := converter.ParseImportedData(context, user, []byte("Time,Type,Sub Category,Account,Amount,Account2,Account2 Amount,Tags\n"+
|
||||
"2024-09-01 00:00:00,Balance Modification,,Test Account,123.45,,,foo;;bar.;#test;hello\tworld;;"), 0, nil, nil, nil)
|
||||
_, _, _, _, _, allNewTags, err := converter.ParseImportedData(context, user, []byte("Time,Type,Sub Category,Account,Amount,Account2,Account2 Amount,Tags\n"+
|
||||
"2024-09-01 00:00:00,Balance Modification,,Test Account,123.45,,,foo;;bar.;#test;hello\tworld;;"), 0, nil, nil, nil, nil, nil)
|
||||
|
||||
assert.Nil(t, err)
|
||||
|
||||
@@ -444,8 +446,8 @@ func TestEzBookKeepingPlainFileConverterParseImportedData_ParseDescription(t *te
|
||||
DefaultCurrency: "CNY",
|
||||
}
|
||||
|
||||
allNewTransactions, _, _, _, err := converter.ParseImportedData(context, user, []byte("Time,Type,Sub Category,Account,Amount,Account2,Account2 Amount,Description\n"+
|
||||
"2024-09-01 12:34:56,Expense,Test Category,Test Account,123.45,,,foo bar\t#test"), 0, nil, nil, nil)
|
||||
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte("Time,Type,Sub Category,Account,Amount,Account2,Account2 Amount,Description\n"+
|
||||
"2024-09-01 12:34:56,Expense,Test Category,Test Account,123.45,,,foo bar\t#test"), 0, nil, nil, nil, nil, nil)
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 1, len(allNewTransactions))
|
||||
@@ -461,7 +463,7 @@ func TestEzBookKeepingPlainFileConverterParseImportedData_MissingFileHeader(t *t
|
||||
DefaultCurrency: "CNY",
|
||||
}
|
||||
|
||||
_, _, _, _, err := converter.ParseImportedData(context, user, []byte(""), 0, nil, nil, nil)
|
||||
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(""), 0, nil, nil, nil, nil, nil)
|
||||
assert.EqualError(t, err, errs.ErrNotFoundTransactionDataInFile.Message)
|
||||
}
|
||||
|
||||
@@ -475,32 +477,32 @@ func TestEzBookKeepingPlainFileConverterParseImportedData_MissingRequiredColumn(
|
||||
}
|
||||
|
||||
// Missing Time Column
|
||||
_, _, _, _, err := converter.ParseImportedData(context, user, []byte("Timezone,Type,Category,Sub Category,Account,Account Currency,Amount,Account2,Account2 Currency,Account2 Amount,Geographic Location,Tags,Description\n"+
|
||||
"+08:00,Balance Modification,,Test Sub Category,Test Account,CNY,123.45,,,,,,"), 0, nil, nil, nil)
|
||||
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte("Timezone,Type,Category,Sub Category,Account,Account Currency,Amount,Account2,Account2 Currency,Account2 Amount,Geographic Location,Tags,Description\n"+
|
||||
"+08:00,Balance Modification,,Test Sub Category,Test Account,CNY,123.45,,,,,,"), 0, nil, nil, nil, nil, nil)
|
||||
assert.EqualError(t, err, errs.ErrMissingRequiredFieldInHeaderRow.Message)
|
||||
|
||||
// Missing Type Column
|
||||
_, _, _, _, err = converter.ParseImportedData(context, user, []byte("Time,Category,Sub Category,Account,Account Currency,Amount,Account2,Account2 Currency,Account2 Amount,Geographic Location,Tags,Description\n"+
|
||||
"2024-09-01 00:00:00,+08:00,Test Category,Test Sub Category,Test Account,CNY,123.45,,,,,,"), 0, nil, nil, nil)
|
||||
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte("Time,Category,Sub Category,Account,Account Currency,Amount,Account2,Account2 Currency,Account2 Amount,Geographic Location,Tags,Description\n"+
|
||||
"2024-09-01 00:00:00,+08:00,Test Category,Test Sub Category,Test Account,CNY,123.45,,,,,,"), 0, nil, nil, nil, nil, nil)
|
||||
assert.EqualError(t, err, errs.ErrMissingRequiredFieldInHeaderRow.Message)
|
||||
|
||||
// Missing Sub Category Column
|
||||
_, _, _, _, err = converter.ParseImportedData(context, user, []byte("Time,Type,Account,Account Currency,Amount,Account2,Account2 Currency,Account2 Amount,Geographic Location,Tags,Description\n"+
|
||||
"2024-09-01 00:00:00,+08:00,Balance Modification,Test Account,CNY,123.45,,,,,,"), 0, nil, nil, nil)
|
||||
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte("Time,Type,Account,Account Currency,Amount,Account2,Account2 Currency,Account2 Amount,Geographic Location,Tags,Description\n"+
|
||||
"2024-09-01 00:00:00,+08:00,Balance Modification,Test Account,CNY,123.45,,,,,,"), 0, nil, nil, nil, nil, nil)
|
||||
assert.EqualError(t, err, errs.ErrMissingRequiredFieldInHeaderRow.Message)
|
||||
|
||||
// Missing Account Name Column
|
||||
_, _, _, _, err = converter.ParseImportedData(context, user, []byte("Time,Timezone,Type,Category,Sub Category,Account Currency,Amount,Account2,Account2 Currency,Account2 Amount,Geographic Location,Tags,Description\n"+
|
||||
"2024-09-01 00:00:00,+08:00,Balance Modification,,Test Sub Category,CNY,123.45,,,,,,"), 0, nil, nil, nil)
|
||||
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte("Time,Timezone,Type,Category,Sub Category,Account Currency,Amount,Account2,Account2 Currency,Account2 Amount,Geographic Location,Tags,Description\n"+
|
||||
"2024-09-01 00:00:00,+08:00,Balance Modification,,Test Sub Category,CNY,123.45,,,,,,"), 0, nil, nil, nil, nil, nil)
|
||||
assert.EqualError(t, err, errs.ErrMissingRequiredFieldInHeaderRow.Message)
|
||||
|
||||
// Missing Amount Column
|
||||
_, _, _, _, err = converter.ParseImportedData(context, user, []byte("Time,Timezone,Type,Category,Sub Category,Account,Account Currency,Account2,Account2 Currency,Account2 Amount,Geographic Location,Tags,Description\n"+
|
||||
"2024-09-01 00:00:00,+08:00,Balance Modification,,Test Sub Category,Test Account,CNY,,,,,,"), 0, nil, nil, nil)
|
||||
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte("Time,Timezone,Type,Category,Sub Category,Account,Account Currency,Account2,Account2 Currency,Account2 Amount,Geographic Location,Tags,Description\n"+
|
||||
"2024-09-01 00:00:00,+08:00,Balance Modification,,Test Sub Category,Test Account,CNY,,,,,,"), 0, nil, nil, nil, nil, nil)
|
||||
assert.EqualError(t, err, errs.ErrMissingRequiredFieldInHeaderRow.Message)
|
||||
|
||||
// Missing Account2 Name Column
|
||||
_, _, _, _, err = converter.ParseImportedData(context, user, []byte("Time,Timezone,Type,Category,Sub Category,Account,Account Currency,Amount,Account2 Currency,Account2 Amount,Geographic Location,Tags,Description\n"+
|
||||
"2024-09-01 00:00:00,+08:00,Balance Modification,,Test Sub Category,Test Account,CNY,123.45,,,,,"), 0, nil, nil, nil)
|
||||
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte("Time,Timezone,Type,Category,Sub Category,Account,Account Currency,Amount,Account2 Currency,Account2 Amount,Geographic Location,Tags,Description\n"+
|
||||
"2024-09-01 00:00:00,+08:00,Balance Modification,,Test Sub Category,Test Account,CNY,123.45,,,,,"), 0, nil, nil, nil, nil, nil)
|
||||
assert.EqualError(t, err, errs.ErrMissingRequiredFieldInHeaderRow.Message)
|
||||
}
|
||||
|
||||
@@ -24,22 +24,22 @@ var (
|
||||
)
|
||||
|
||||
// ParseImportedData returns the imported data by parsing the feidee mymoney transaction csv data
|
||||
func (c *feideeMymoneyTransactionDataCsvImporter) ParseImportedData(ctx core.Context, user *models.User, data []byte, defaultTimezoneOffset int16, accountMap map[string]*models.Account, categoryMap map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionTag, error) {
|
||||
func (c *feideeMymoneyTransactionDataCsvImporter) ParseImportedData(ctx core.Context, user *models.User, data []byte, defaultTimezoneOffset int16, accountMap map[string]*models.Account, expenseCategoryMap map[string]*models.TransactionCategory, incomeCategoryMap map[string]*models.TransactionCategory, transferCategoryMap map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionTag, error) {
|
||||
content := string(data)
|
||||
|
||||
if strings.Index(content, feideeMymoneyTransactionDataCsvFileHeader) != 0 && strings.Index(content, feideeMymoneyTransactionDataCsvFileHeaderWithUtf8Bom) != 0 {
|
||||
return nil, nil, nil, nil, errs.ErrInvalidFileHeader
|
||||
return nil, nil, nil, nil, nil, nil, errs.ErrInvalidFileHeader
|
||||
}
|
||||
|
||||
allLines, err := c.parseAllLinesFromCsvData(ctx, content)
|
||||
|
||||
if err != nil {
|
||||
return nil, nil, nil, nil, err
|
||||
return nil, nil, nil, nil, nil, nil, err
|
||||
}
|
||||
|
||||
if len(allLines) <= 1 {
|
||||
log.Errorf(ctx, "[feidee_mymoney_transaction_data_csv_file_importer.ParseImportedData] cannot parse import data for user \"uid:%d\", because data table row count is less 1", user.Uid)
|
||||
return nil, nil, nil, nil, errs.ErrNotFoundTransactionDataInFile
|
||||
return nil, nil, nil, nil, nil, nil, errs.ErrNotFoundTransactionDataInFile
|
||||
}
|
||||
|
||||
headerLineItems := allLines[0]
|
||||
@@ -62,7 +62,7 @@ func (c *feideeMymoneyTransactionDataCsvImporter) ParseImportedData(ctx core.Con
|
||||
if !timeColumnExists || !typeColumnExists || !subCategoryColumnExists ||
|
||||
!accountColumnExists || !amountColumnExists || !relatedIdColumnExists {
|
||||
log.Errorf(ctx, "[feidee_mymoney_transaction_data_csv_file_importer.ParseImportedData] cannot parse import data for user \"uid:%d\", because missing essential columns in header row", user.Uid)
|
||||
return nil, nil, nil, nil, errs.ErrMissingRequiredFieldInHeaderRow
|
||||
return nil, nil, nil, nil, nil, nil, errs.ErrMissingRequiredFieldInHeaderRow
|
||||
}
|
||||
|
||||
newColumns := make([]datatable.DataTableColumn, 0, 11)
|
||||
@@ -121,7 +121,7 @@ func (c *feideeMymoneyTransactionDataCsvImporter) ParseImportedData(ctx core.Con
|
||||
|
||||
if len(items) < len(headerLineItems) {
|
||||
log.Errorf(ctx, "[feidee_mymoney_transaction_data_csv_file_importer.ParseImportedData] cannot parse row \"index:%d\" for user \"uid:%d\", because may missing some columns (column count %d in data row is less than header column count %d)", i, user.Uid, len(items), len(headerLineItems))
|
||||
return nil, nil, nil, nil, errs.ErrFewerFieldsInDataRowThanInHeaderRow
|
||||
return nil, nil, nil, nil, nil, nil, errs.ErrFewerFieldsInDataRowThanInHeaderRow
|
||||
}
|
||||
|
||||
transactionType := data[datatable.DATA_TABLE_TRANSACTION_TYPE]
|
||||
@@ -142,7 +142,7 @@ func (c *feideeMymoneyTransactionDataCsvImporter) ParseImportedData(ctx core.Con
|
||||
} else if transactionType == "转入" || transactionType == "转出" {
|
||||
if relatedId == "" {
|
||||
log.Errorf(ctx, "[feidee_mymoney_transaction_data_csv_file_importer.ParseImportedData] transfer transaction has blank related id in row \"index:%d\" for user \"uid:%d\"", i, user.Uid)
|
||||
return nil, nil, nil, nil, errs.ErrRelatedIdCannotBeBlank
|
||||
return nil, nil, nil, nil, nil, nil, errs.ErrRelatedIdCannotBeBlank
|
||||
}
|
||||
|
||||
relatedData, exists := transferTransactionsMap[relatedId]
|
||||
@@ -168,17 +168,17 @@ func (c *feideeMymoneyTransactionDataCsvImporter) ParseImportedData(ctx core.Con
|
||||
delete(transferTransactionsMap, relatedId)
|
||||
} else {
|
||||
log.Errorf(ctx, "[feidee_mymoney_transaction_data_csv_file_importer.ParseImportedData] transfer transaction type \"%s\" is not expected in row \"index:%d\" for user \"uid:%d\"", transactionType, i, user.Uid)
|
||||
return nil, nil, nil, nil, errs.ErrTransactionTypeInvalid
|
||||
return nil, nil, nil, nil, nil, nil, errs.ErrTransactionTypeInvalid
|
||||
}
|
||||
} else {
|
||||
log.Errorf(ctx, "[feidee_mymoney_transaction_data_csv_file_importer.ParseImportedData] cannot parse transaction type \"%s\" in row \"index:%d\" for user \"uid:%d\"", transactionType, i, user.Uid)
|
||||
return nil, nil, nil, nil, errs.ErrTransactionTypeInvalid
|
||||
return nil, nil, nil, nil, nil, nil, errs.ErrTransactionTypeInvalid
|
||||
}
|
||||
}
|
||||
|
||||
if len(transferTransactionsMap) > 0 {
|
||||
log.Errorf(ctx, "[feidee_mymoney_transaction_data_csv_file_importer.ParseImportedData] there are %d transactions (related id is %s) which don't have related records", len(transferTransactionsMap), c.getRelatedIds(transferTransactionsMap))
|
||||
return nil, nil, nil, nil, errs.ErrFoundRecordNotHasRelatedRecord
|
||||
return nil, nil, nil, nil, nil, nil, errs.ErrFoundRecordNotHasRelatedRecord
|
||||
}
|
||||
|
||||
dataTableImporter := datatable.CreateNewSimpleImporterFromWritableDataTableWithPostProcessFunc(
|
||||
@@ -187,7 +187,7 @@ func (c *feideeMymoneyTransactionDataCsvImporter) ParseImportedData(ctx core.Con
|
||||
feideeMymoneyTransactionDataImporterPostProcess,
|
||||
)
|
||||
|
||||
return dataTableImporter.ParseImportedData(ctx, user, dataTable, defaultTimezoneOffset, accountMap, categoryMap, tagMap)
|
||||
return dataTableImporter.ParseImportedData(ctx, user, dataTable, defaultTimezoneOffset, accountMap, expenseCategoryMap, incomeCategoryMap, transferCategoryMap, tagMap)
|
||||
}
|
||||
|
||||
func (c *feideeMymoneyTransactionDataCsvImporter) parseAllLinesFromCsvData(ctx core.Context, content string) ([][]string, error) {
|
||||
|
||||
@@ -21,7 +21,7 @@ func TestFeideeMymoneyCsvFileImporterParseImportedData_MinimumValidData(t *testi
|
||||
DefaultCurrency: "CNY",
|
||||
}
|
||||
|
||||
allNewTransactions, allNewAccounts, allNewSubCategories, allNewTags, err := converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
|
||||
allNewTransactions, allNewAccounts, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, allNewTags, err := converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
|
||||
"\"交易类型\",\"日期\",\"子类别\",\"账户\",\"金额\",\"备注\",\"关联Id\"\n"+
|
||||
"\"余额变更\",\"2024-09-01 00:00:00\",\"\",\"Test Account\",\"123.45\",\"\",\"\"\n"+
|
||||
"\"余额变更\",\"2024-09-01 01:00:00\",\"\",\"Test Account2\",\"-0.12\",\"\",\"\"\n"+
|
||||
@@ -30,13 +30,15 @@ func TestFeideeMymoneyCsvFileImporterParseImportedData_MinimumValidData(t *testi
|
||||
"\"转出\",\"2024-09-01 23:59:59\",\"Test Category3\",\"Test Account\",\"0.05\",\"\",\"00000000-0000-0000-0000-000000000001\"\n"+
|
||||
"\"转入\",\"2024-09-01 23:59:59\",\"Test Category3\",\"Test Account2\",\"0.05\",\"\",\"00000000-0000-0000-0000-000000000001\"\n"+
|
||||
"\"转入\",\"2024-09-02 23:59:59\",\"Test Category3\",\"Test Account\",\"0.5\",\"\",\"00000000-0000-0000-0000-000000000002\"\n"+
|
||||
"\"转出\",\"2024-09-02 23:59:59\",\"Test Category3\",\"Test Account2\",\"0.5\",\"\",\"00000000-0000-0000-0000-000000000002\""), 0, nil, nil, nil)
|
||||
"\"转出\",\"2024-09-02 23:59:59\",\"Test Category3\",\"Test Account2\",\"0.5\",\"\",\"00000000-0000-0000-0000-000000000002\""), 0, nil, nil, nil, nil, nil)
|
||||
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.Equal(t, 6, len(allNewTransactions))
|
||||
assert.Equal(t, 2, len(allNewAccounts))
|
||||
assert.Equal(t, 3, len(allNewSubCategories))
|
||||
assert.Equal(t, 1, len(allNewSubExpenseCategories))
|
||||
assert.Equal(t, 1, len(allNewSubIncomeCategories))
|
||||
assert.Equal(t, 1, len(allNewSubTransferCategories))
|
||||
assert.Equal(t, 0, len(allNewTags))
|
||||
|
||||
assert.Equal(t, int64(1234567890), allNewTransactions[0].Uid)
|
||||
@@ -91,14 +93,14 @@ func TestFeideeMymoneyCsvFileImporterParseImportedData_MinimumValidData(t *testi
|
||||
assert.Equal(t, "Test Account2", allNewAccounts[1].Name)
|
||||
assert.Equal(t, "CNY", allNewAccounts[1].Currency)
|
||||
|
||||
assert.Equal(t, int64(1234567890), allNewSubCategories[0].Uid)
|
||||
assert.Equal(t, "Test Category", allNewSubCategories[0].Name)
|
||||
assert.Equal(t, int64(1234567890), allNewSubExpenseCategories[0].Uid)
|
||||
assert.Equal(t, "Test Category2", allNewSubExpenseCategories[0].Name)
|
||||
|
||||
assert.Equal(t, int64(1234567890), allNewSubCategories[1].Uid)
|
||||
assert.Equal(t, "Test Category2", allNewSubCategories[1].Name)
|
||||
assert.Equal(t, int64(1234567890), allNewSubIncomeCategories[0].Uid)
|
||||
assert.Equal(t, "Test Category", allNewSubIncomeCategories[0].Name)
|
||||
|
||||
assert.Equal(t, int64(1234567890), allNewSubCategories[2].Uid)
|
||||
assert.Equal(t, "Test Category3", allNewSubCategories[2].Name)
|
||||
assert.Equal(t, int64(1234567890), allNewSubTransferCategories[0].Uid)
|
||||
assert.Equal(t, "Test Category3", allNewSubTransferCategories[0].Name)
|
||||
}
|
||||
|
||||
func TestFeideeMymoneyCsvFileImporterParseImportedData_ParseInvalidTime(t *testing.T) {
|
||||
@@ -110,14 +112,14 @@ func TestFeideeMymoneyCsvFileImporterParseImportedData_ParseInvalidTime(t *testi
|
||||
DefaultCurrency: "CNY",
|
||||
}
|
||||
|
||||
_, _, _, _, err := converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
|
||||
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
|
||||
"\"交易类型\",\"日期\",\"子类别\",\"账户\",\"金额\",\"备注\",\"关联Id\"\n"+
|
||||
"\"收入\",\"2024-09-01T12:34:56\",\"Test Category\",\"Test Account\",\"0.12\",\"\",\"\""), 0, nil, nil, nil)
|
||||
"\"收入\",\"2024-09-01T12:34:56\",\"Test Category\",\"Test Account\",\"0.12\",\"\",\"\""), 0, nil, nil, nil, nil, nil)
|
||||
assert.EqualError(t, err, errs.ErrTransactionTimeInvalid.Message)
|
||||
|
||||
_, _, _, _, err = converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
|
||||
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
|
||||
"\"交易类型\",\"日期\",\"子类别\",\"账户\",\"金额\",\"备注\",\"关联Id\"\n"+
|
||||
"\"收入\",\"09/01/2024 12:34:56\",\"Test Category\",\"Test Account\",\"0.12\",\"\",\"\""), 0, nil, nil, nil)
|
||||
"\"收入\",\"09/01/2024 12:34:56\",\"Test Category\",\"Test Account\",\"0.12\",\"\",\"\""), 0, nil, nil, nil, nil, nil)
|
||||
assert.EqualError(t, err, errs.ErrTransactionTimeInvalid.Message)
|
||||
}
|
||||
|
||||
@@ -130,9 +132,9 @@ func TestFeideeMymoneyCsvFileImporterParseImportedData_ParseInvalidType(t *testi
|
||||
DefaultCurrency: "CNY",
|
||||
}
|
||||
|
||||
_, _, _, _, err := converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
|
||||
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
|
||||
"\"交易类型\",\"日期\",\"子类别\",\"账户\",\"金额\",\"备注\",\"关联Id\"\n"+
|
||||
"\"Type\",\"2024-09-01 12:34:56\",\"Test Category\",\"Test Account\",\"0.12\",\"\",\"\""), 0, nil, nil, nil)
|
||||
"\"Type\",\"2024-09-01 12:34:56\",\"Test Category\",\"Test Account\",\"0.12\",\"\",\"\""), 0, nil, nil, nil, nil, nil)
|
||||
assert.EqualError(t, err, errs.ErrTransactionTypeInvalid.Message)
|
||||
}
|
||||
|
||||
@@ -145,11 +147,11 @@ func TestFeideeMymoneyCsvFileImporterParseImportedData_ParseValidAccountCurrency
|
||||
DefaultCurrency: "CNY",
|
||||
}
|
||||
|
||||
allNewTransactions, allNewAccounts, _, _, err := converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
|
||||
allNewTransactions, allNewAccounts, _, _, _, _, err := converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
|
||||
"\"交易类型\",\"日期\",\"子类别\",\"账户\",\"账户币种\",\"金额\",\"备注\",\"关联Id\"\n"+
|
||||
"\"余额变更\",\"2024-09-01 01:23:45\",\"\",\"Test Account\",\"USD\",\"123.45\",\"\",\"\"\n"+
|
||||
"\"转出\",\"2024-09-01 12:34:56\",\"Test Category3\",\"Test Account\",\"USD\",\"1.23\",\"\",\"00000000-0000-0000-0000-000000000001\"\n"+
|
||||
"\"转入\",\"2024-09-01 12:34:56\",\"Test Category3\",\"Test Account2\",\"EUR\",\"1.10\",\"\",\"00000000-0000-0000-0000-000000000001\""), 0, nil, nil, nil)
|
||||
"\"转入\",\"2024-09-01 12:34:56\",\"Test Category3\",\"Test Account2\",\"EUR\",\"1.10\",\"\",\"00000000-0000-0000-0000-000000000001\""), 0, nil, nil, nil, nil, nil)
|
||||
|
||||
assert.Nil(t, err)
|
||||
|
||||
@@ -174,18 +176,18 @@ func TestFeideeMymoneyCsvFileImporterParseImportedData_ParseInvalidAccountCurren
|
||||
DefaultCurrency: "CNY",
|
||||
}
|
||||
|
||||
_, _, _, _, err := converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
|
||||
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
|
||||
"\"交易类型\",\"日期\",\"子类别\",\"账户\",\"账户币种\",\"金额\",\"备注\",\"关联Id\"\n"+
|
||||
"\"余额变更\",\"2024-09-01 01:23:45\",\"\",\"Test Account\",\"USD\",\"123.45\",\"\",\"\"\n"+
|
||||
"\"转出\",\"2024-09-01 12:34:56\",\"Test Category3\",\"Test Account\",\"CNY\",\"1.23\",\"\",\"00000000-0000-0000-0000-000000000001\"\n"+
|
||||
"\"转入\",\"2024-09-01 12:34:56\",\"Test Category3\",\"Test Account2\",\"EUR\",\"1.10\",\"\",\"00000000-0000-0000-0000-000000000001\""), 0, nil, nil, nil)
|
||||
"\"转入\",\"2024-09-01 12:34:56\",\"Test Category3\",\"Test Account2\",\"EUR\",\"1.10\",\"\",\"00000000-0000-0000-0000-000000000001\""), 0, nil, nil, nil, nil, nil)
|
||||
assert.EqualError(t, err, errs.ErrAccountCurrencyInvalid.Message)
|
||||
|
||||
_, _, _, _, err = converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
|
||||
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
|
||||
"\"交易类型\",\"日期\",\"子类别\",\"账户\",\"账户币种\",\"金额\",\"备注\",\"关联Id\"\n"+
|
||||
"\"余额变更\",\"2024-09-01 01:23:45\",\"\",\"Test Account\",\"USD\",\"123.45\",\"\",\"\"\n"+
|
||||
"\"转出\",\"2024-09-01 12:34:56\",\"Test Category3\",\"Test Account2\",\"CNY\",\"1.23\",\"\",\"00000000-0000-0000-0000-000000000001\"\n"+
|
||||
"\"转入\",\"2024-09-01 12:34:56\",\"Test Category3\",\"Test Account\",\"EUR\",\"1.10\",\"\",\"00000000-0000-0000-0000-000000000001\""), 0, nil, nil, nil)
|
||||
"\"转入\",\"2024-09-01 12:34:56\",\"Test Category3\",\"Test Account\",\"EUR\",\"1.10\",\"\",\"00000000-0000-0000-0000-000000000001\""), 0, nil, nil, nil, nil, nil)
|
||||
assert.EqualError(t, err, errs.ErrAccountCurrencyInvalid.Message)
|
||||
}
|
||||
|
||||
@@ -198,21 +200,21 @@ func TestFeideeMymoneyCsvFileImporterParseImportedData_ParseNotSupportedCurrency
|
||||
DefaultCurrency: "CNY",
|
||||
}
|
||||
|
||||
_, _, _, _, err := converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
|
||||
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
|
||||
"\"交易类型\",\"日期\",\"子类别\",\"账户\",\"账户币种\",\"金额\",\"备注\",\"关联Id\"\n"+
|
||||
"\"余额变更\",\"2024-09-01 01:23:45\",\"\",\"Test Account\",\"XXX\",\"123.45\",\"\",\"\""), 0, nil, nil, nil)
|
||||
"\"余额变更\",\"2024-09-01 01:23:45\",\"\",\"Test Account\",\"XXX\",\"123.45\",\"\",\"\""), 0, nil, nil, nil, nil, nil)
|
||||
assert.EqualError(t, err, errs.ErrAccountCurrencyInvalid.Message)
|
||||
|
||||
_, _, _, _, err = converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
|
||||
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
|
||||
"\"交易类型\",\"日期\",\"子类别\",\"账户\",\"账户币种\",\"金额\",\"备注\",\"关联Id\"\n"+
|
||||
"\"转出\",\"2024-09-01 12:34:56\",\"Test Category\",\"Test Account\",\"USD\",\"123.45\",\"\",\"00000000-0000-0000-0000-000000000001\"\n"+
|
||||
"\"转入\",\"2024-09-01 12:34:56\",\"Test Category\",\"Test Account2\",\"XXX\",\"123.45\",\"\",\"00000000-0000-0000-0000-000000000001\""), 0, nil, nil, nil)
|
||||
"\"转入\",\"2024-09-01 12:34:56\",\"Test Category\",\"Test Account2\",\"XXX\",\"123.45\",\"\",\"00000000-0000-0000-0000-000000000001\""), 0, nil, nil, nil, nil, nil)
|
||||
assert.EqualError(t, err, errs.ErrAccountCurrencyInvalid.Message)
|
||||
|
||||
_, _, _, _, err = converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
|
||||
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
|
||||
"\"交易类型\",\"日期\",\"子类别\",\"账户\",\"账户币种\",\"金额\",\"备注\",\"关联Id\"\n"+
|
||||
"\"转出\",\"2024-09-01 12:34:56\",\"Test Category\",\"Test Account\",\"XXX\",\"123.45\",\"\",\"00000000-0000-0000-0000-000000000001\"\n"+
|
||||
"\"转入\",\"2024-09-01 12:34:56\",\"Test Category\",\"Test Account2\",\"USD\",\"123.45\",\"\",\"00000000-0000-0000-0000-000000000001\""), 0, nil, nil, nil)
|
||||
"\"转入\",\"2024-09-01 12:34:56\",\"Test Category\",\"Test Account2\",\"USD\",\"123.45\",\"\",\"00000000-0000-0000-0000-000000000001\""), 0, nil, nil, nil, nil, nil)
|
||||
assert.EqualError(t, err, errs.ErrAccountCurrencyInvalid.Message)
|
||||
}
|
||||
|
||||
@@ -225,21 +227,21 @@ func TestFeideeMymoneyCsvFileImporterParseImportedData_ParseInvalidAmount(t *tes
|
||||
DefaultCurrency: "CNY",
|
||||
}
|
||||
|
||||
_, _, _, _, err := converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
|
||||
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
|
||||
"\"交易类型\",\"日期\",\"子类别\",\"账户\",\"金额\",\"备注\",\"关联Id\"\n"+
|
||||
"\"余额变更\",\"2024-09-01 01:23:45\",\"\",\"Test Account\",\"123 45\",\"\",\"\""), 0, nil, nil, nil)
|
||||
"\"余额变更\",\"2024-09-01 01:23:45\",\"\",\"Test Account\",\"123 45\",\"\",\"\""), 0, nil, nil, nil, nil, nil)
|
||||
assert.EqualError(t, err, errs.ErrAmountInvalid.Message)
|
||||
|
||||
_, _, _, _, err = converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
|
||||
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
|
||||
"\"交易类型\",\"日期\",\"子类别\",\"账户\",\"金额\",\"备注\",\"关联Id\"\n"+
|
||||
"\"转出\",\"2024-09-01 12:34:56\",\"Test Category\",\"Test Account\",\"123 45\",\"\",\"00000000-0000-0000-0000-000000000001\"\n"+
|
||||
"\"转入\",\"2024-09-01 12:34:56\",\"Test Category\",\"Test Account2\",\"123.45\",\"\",\"00000000-0000-0000-0000-000000000001\""), 0, nil, nil, nil)
|
||||
"\"转入\",\"2024-09-01 12:34:56\",\"Test Category\",\"Test Account2\",\"123.45\",\"\",\"00000000-0000-0000-0000-000000000001\""), 0, nil, nil, nil, nil, nil)
|
||||
assert.EqualError(t, err, errs.ErrAmountInvalid.Message)
|
||||
|
||||
_, _, _, _, err = converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
|
||||
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
|
||||
"\"交易类型\",\"日期\",\"子类别\",\"账户\",\"金额\",\"备注\",\"关联Id\"\n"+
|
||||
"\"转出\",\"2024-09-01 12:34:56\",\"Test Category\",\"Test Account\",\"123.45\",\"\",\"00000000-0000-0000-0000-000000000001\"\n"+
|
||||
"\"转入\",\"2024-09-01 12:34:56\",\"Test Category\",\"Test Account2\",\"123 45\",\"\",\"00000000-0000-0000-0000-000000000001\""), 0, nil, nil, nil)
|
||||
"\"转入\",\"2024-09-01 12:34:56\",\"Test Category\",\"Test Account2\",\"123 45\",\"\",\"00000000-0000-0000-0000-000000000001\""), 0, nil, nil, nil, nil, nil)
|
||||
assert.EqualError(t, err, errs.ErrAmountInvalid.Message)
|
||||
}
|
||||
|
||||
@@ -252,10 +254,10 @@ func TestFeideeMymoneyCsvFileImporterParseImportedData_ParseDescription(t *testi
|
||||
DefaultCurrency: "CNY",
|
||||
}
|
||||
|
||||
allNewTransactions, _, _, _, err := converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
|
||||
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
|
||||
"\"交易类型\",\"日期\",\"子类别\",\"账户\",\"金额\",\"备注\",\"关联Id\"\n"+
|
||||
"\"支出\",\"2024-09-01 12:34:56\",\"Test Category\",\"Test Account\",\"123.45\",\"Test\n"+
|
||||
"A new line break\",\"\""), 0, nil, nil, nil)
|
||||
"A new line break\",\"\""), 0, nil, nil, nil, nil, nil)
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 1, len(allNewTransactions))
|
||||
@@ -271,20 +273,20 @@ func TestFeideeMymoneyCsvFileImporterParseImportedData_InvalidRelatedId(t *testi
|
||||
DefaultCurrency: "CNY",
|
||||
}
|
||||
|
||||
_, _, _, _, err := converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
|
||||
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
|
||||
"\"交易类型\",\"日期\",\"子类别\",\"账户\",\"金额\",\"备注\",\"关联Id\"\n"+
|
||||
"\"转出\",\"2024-09-01 23:59:59\",\"Test Category3\",\"Test Account\",\"0.05\",\"\",\"\""), 0, nil, nil, nil)
|
||||
"\"转出\",\"2024-09-01 23:59:59\",\"Test Category3\",\"Test Account\",\"0.05\",\"\",\"\""), 0, nil, nil, nil, nil, nil)
|
||||
assert.EqualError(t, err, errs.ErrRelatedIdCannotBeBlank.Message)
|
||||
|
||||
_, _, _, _, err = converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
|
||||
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
|
||||
"\"交易类型\",\"日期\",\"子类别\",\"账户\",\"金额\",\"备注\",\"关联Id\"\n"+
|
||||
"\"转入\",\"2024-09-01 23:59:59\",\"Test Category3\",\"Test Account\",\"0.05\",\"\",\"\""), 0, nil, nil, nil)
|
||||
"\"转入\",\"2024-09-01 23:59:59\",\"Test Category3\",\"Test Account\",\"0.05\",\"\",\"\""), 0, nil, nil, nil, nil, nil)
|
||||
assert.EqualError(t, err, errs.ErrRelatedIdCannotBeBlank.Message)
|
||||
|
||||
_, _, _, _, err = converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
|
||||
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
|
||||
"\"交易类型\",\"日期\",\"子类别\",\"账户\",\"金额\",\"备注\",\"关联Id\"\n"+
|
||||
"\"转出\",\"2024-09-01 23:59:59\",\"Test Category3\",\"Test Account\",\"0.05\",\"\",\"00000000-0000-0000-0000-000000000001\"\n"+
|
||||
"\"转入\",\"2024-09-02 23:59:59\",\"Test Category3\",\"Test Account\",\"0.5\",\"\",\"00000000-0000-0000-0000-000000000002\""), 0, nil, nil, nil)
|
||||
"\"转入\",\"2024-09-02 23:59:59\",\"Test Category3\",\"Test Account\",\"0.5\",\"\",\"00000000-0000-0000-0000-000000000002\""), 0, nil, nil, nil, nil, nil)
|
||||
assert.EqualError(t, err, errs.ErrFoundRecordNotHasRelatedRecord.Message)
|
||||
}
|
||||
|
||||
@@ -296,11 +298,11 @@ func TestFeideeMymoneyCsvFileImporterParseImportedData_MissingFileHeader(t *test
|
||||
Uid: 1,
|
||||
DefaultCurrency: "CNY",
|
||||
}
|
||||
_, _, _, _, err := converter.ParseImportedData(context, user, []byte("\"交易类型\",\"日期\",\"子类别\",\"账户\",\"金额\",\"备注\",\"关联Id\"\n"+
|
||||
"\"余额变更\",\"2024-09-01 00:00:00\",\"\",\"Test Account\",\"123.45\",\"\",\"\"\n"), 0, nil, nil, nil)
|
||||
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte("\"交易类型\",\"日期\",\"子类别\",\"账户\",\"金额\",\"备注\",\"关联Id\"\n"+
|
||||
"\"余额变更\",\"2024-09-01 00:00:00\",\"\",\"Test Account\",\"123.45\",\"\",\"\"\n"), 0, nil, nil, nil, nil, nil)
|
||||
assert.EqualError(t, err, errs.ErrInvalidFileHeader.Message)
|
||||
|
||||
_, _, _, _, err = converter.ParseImportedData(context, user, []byte(""), 0, nil, nil, nil)
|
||||
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(""), 0, nil, nil, nil, nil, nil)
|
||||
assert.EqualError(t, err, errs.ErrInvalidFileHeader.Message)
|
||||
}
|
||||
|
||||
@@ -314,38 +316,38 @@ func TestFeideeMymoneyCsvFileImporterParseImportedData_MissingRequiredColumn(t *
|
||||
}
|
||||
|
||||
// Missing Time Column
|
||||
_, _, _, _, err := converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
|
||||
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
|
||||
"\"交易类型\",\"子类别\",\"账户\",\"金额\",\"备注\",\"关联Id\"\n"+
|
||||
"\"余额变更\",\"\",\"Test Account\",\"123.45\",\"\",\"\"\n"), 0, nil, nil, nil)
|
||||
"\"余额变更\",\"\",\"Test Account\",\"123.45\",\"\",\"\"\n"), 0, nil, nil, nil, nil, nil)
|
||||
assert.EqualError(t, err, errs.ErrMissingRequiredFieldInHeaderRow.Message)
|
||||
|
||||
// Missing Type Column
|
||||
_, _, _, _, err = converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
|
||||
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
|
||||
"\"日期\",\"子类别\",\"账户\",\"金额\",\"备注\",\"关联Id\"\n"+
|
||||
"\"2024-09-01 00:00:00\",\"Test Category\",\"Test Account\",\"123.45\",\"\",\"\"\n"), 0, nil, nil, nil)
|
||||
"\"2024-09-01 00:00:00\",\"Test Category\",\"Test Account\",\"123.45\",\"\",\"\"\n"), 0, nil, nil, nil, nil, nil)
|
||||
assert.EqualError(t, err, errs.ErrMissingRequiredFieldInHeaderRow.Message)
|
||||
|
||||
// Missing Sub Category Column
|
||||
_, _, _, _, err = converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
|
||||
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
|
||||
"\"交易类型\",\"日期\",\"账户\",\"金额\",\"备注\",\"关联Id\"\n"+
|
||||
"\"余额变更\",\"2024-09-01 00:00:00\",\"Test Account\",\"123.45\",\"\",\"\"\n"), 0, nil, nil, nil)
|
||||
"\"余额变更\",\"2024-09-01 00:00:00\",\"Test Account\",\"123.45\",\"\",\"\"\n"), 0, nil, nil, nil, nil, nil)
|
||||
assert.EqualError(t, err, errs.ErrMissingRequiredFieldInHeaderRow.Message)
|
||||
|
||||
// Missing Account Name Column
|
||||
_, _, _, _, err = converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
|
||||
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
|
||||
"\"交易类型\",\"日期\",\"子类别\",\"金额\",\"备注\",\"关联Id\"\n"+
|
||||
"\"余额变更\",\"2024-09-01 00:00:00\",\"\",\"123.45\",\"\",\"\"\n"), 0, nil, nil, nil)
|
||||
"\"余额变更\",\"2024-09-01 00:00:00\",\"\",\"123.45\",\"\",\"\"\n"), 0, nil, nil, nil, nil, nil)
|
||||
assert.EqualError(t, err, errs.ErrMissingRequiredFieldInHeaderRow.Message)
|
||||
|
||||
// Missing Amount Column
|
||||
_, _, _, _, err = converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
|
||||
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
|
||||
"\"交易类型\",\"日期\",\"子类别\",\"账户\",\"备注\",\"关联Id\"\n"+
|
||||
"\"余额变更\",\"2024-09-01 00:00:00\",\"\",\"Test Account\",\"\",\"\"\n"), 0, nil, nil, nil)
|
||||
"\"余额变更\",\"2024-09-01 00:00:00\",\"\",\"Test Account\",\"\",\"\"\n"), 0, nil, nil, nil, nil, nil)
|
||||
assert.EqualError(t, err, errs.ErrMissingRequiredFieldInHeaderRow.Message)
|
||||
|
||||
// Missing Related ID Column
|
||||
_, _, _, _, err = converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
|
||||
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
|
||||
"\"交易类型\",\"日期\",\"子类别\",\"账户\",\"金额\",\"备注\"\n"+
|
||||
"\"余额变更\",\"2024-09-01 00:00:00\",\"\",\"Test Account\",\"123.45\",\"\"\n"), 0, nil, nil, nil)
|
||||
"\"余额变更\",\"2024-09-01 00:00:00\",\"\",\"Test Account\",\"123.45\",\"\"\n"), 0, nil, nil, nil, nil, nil)
|
||||
assert.EqualError(t, err, errs.ErrMissingRequiredFieldInHeaderRow.Message)
|
||||
}
|
||||
|
||||
@@ -17,11 +17,11 @@ var (
|
||||
)
|
||||
|
||||
// ParseImportedData returns the imported data by parsing the feidee mymoney transaction xls data
|
||||
func (c *feideeMymoneyTransactionDataXlsImporter) ParseImportedData(ctx core.Context, user *models.User, data []byte, defaultTimezoneOffset int16, accountMap map[string]*models.Account, categoryMap map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionTag, error) {
|
||||
func (c *feideeMymoneyTransactionDataXlsImporter) ParseImportedData(ctx core.Context, user *models.User, data []byte, defaultTimezoneOffset int16, accountMap map[string]*models.Account, expenseCategoryMap map[string]*models.TransactionCategory, incomeCategoryMap map[string]*models.TransactionCategory, transferCategoryMap map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionTag, error) {
|
||||
dataTable, err := createNewFeideeMymoneyTransactionExcelFileDataTable(data)
|
||||
|
||||
if err != nil {
|
||||
return nil, nil, nil, nil, err
|
||||
return nil, nil, nil, nil, nil, nil, err
|
||||
}
|
||||
|
||||
dataTableImporter := datatable.CreateNewSimpleImporterWithPostProcessFunc(
|
||||
@@ -30,5 +30,5 @@ func (c *feideeMymoneyTransactionDataXlsImporter) ParseImportedData(ctx core.Con
|
||||
feideeMymoneyTransactionDataImporterPostProcess,
|
||||
)
|
||||
|
||||
return dataTableImporter.ParseImportedData(ctx, user, dataTable, defaultTimezoneOffset, accountMap, categoryMap, tagMap)
|
||||
return dataTableImporter.ParseImportedData(ctx, user, dataTable, defaultTimezoneOffset, accountMap, expenseCategoryMap, incomeCategoryMap, transferCategoryMap, tagMap)
|
||||
}
|
||||
|
||||
@@ -24,12 +24,14 @@ func TestFeideeMymoneyTransactionDataXlsImporterParseImportedData_MinimumValidDa
|
||||
testdata, err := os.ReadFile("../../../testdata/feidee_mymoney_test_file.xls")
|
||||
assert.Nil(t, err)
|
||||
|
||||
allNewTransactions, allNewAccounts, allNewSubCategories, allNewTags, err := converter.ParseImportedData(context, user, testdata, 0, nil, nil, nil)
|
||||
allNewTransactions, allNewAccounts, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, allNewTags, err := converter.ParseImportedData(context, user, testdata, 0, nil, nil, nil, nil, nil)
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.Equal(t, 7, len(allNewTransactions))
|
||||
assert.Equal(t, 2, len(allNewAccounts))
|
||||
assert.Equal(t, 5, len(allNewSubCategories))
|
||||
assert.Equal(t, 2, len(allNewSubExpenseCategories))
|
||||
assert.Equal(t, 2, len(allNewSubIncomeCategories))
|
||||
assert.Equal(t, 1, len(allNewSubTransferCategories))
|
||||
assert.Equal(t, 0, len(allNewTags))
|
||||
|
||||
assert.Equal(t, int64(1234567890), allNewTransactions[0].Uid)
|
||||
@@ -92,18 +94,18 @@ func TestFeideeMymoneyTransactionDataXlsImporterParseImportedData_MinimumValidDa
|
||||
assert.Equal(t, "Test Account2", allNewAccounts[1].Name)
|
||||
assert.Equal(t, "CNY", allNewAccounts[1].Currency)
|
||||
|
||||
assert.Equal(t, int64(1234567890), allNewSubCategories[0].Uid)
|
||||
assert.Equal(t, "Test Category", allNewSubCategories[0].Name)
|
||||
assert.Equal(t, int64(1234567890), allNewSubExpenseCategories[0].Uid)
|
||||
assert.Equal(t, "Test Category2", allNewSubExpenseCategories[0].Name)
|
||||
|
||||
assert.Equal(t, int64(1234567890), allNewSubCategories[1].Uid)
|
||||
assert.Equal(t, "Test Category5", allNewSubCategories[1].Name)
|
||||
assert.Equal(t, int64(1234567890), allNewSubExpenseCategories[1].Uid)
|
||||
assert.Equal(t, "Test Category4", allNewSubExpenseCategories[1].Name)
|
||||
|
||||
assert.Equal(t, int64(1234567890), allNewSubCategories[2].Uid)
|
||||
assert.Equal(t, "Test Category2", allNewSubCategories[2].Name)
|
||||
assert.Equal(t, int64(1234567890), allNewSubIncomeCategories[0].Uid)
|
||||
assert.Equal(t, "Test Category", allNewSubIncomeCategories[0].Name)
|
||||
|
||||
assert.Equal(t, int64(1234567890), allNewSubCategories[3].Uid)
|
||||
assert.Equal(t, "Test Category4", allNewSubCategories[3].Name)
|
||||
assert.Equal(t, int64(1234567890), allNewSubIncomeCategories[1].Uid)
|
||||
assert.Equal(t, "Test Category5", allNewSubIncomeCategories[1].Name)
|
||||
|
||||
assert.Equal(t, int64(1234567890), allNewSubCategories[4].Uid)
|
||||
assert.Equal(t, "Test Category3", allNewSubCategories[4].Name)
|
||||
assert.Equal(t, int64(1234567890), allNewSubTransferCategories[0].Uid)
|
||||
assert.Equal(t, "Test Category3", allNewSubTransferCategories[0].Name)
|
||||
}
|
||||
|
||||
@@ -449,14 +449,24 @@ func (s *TransactionCategoryService) GetCategoryMapByList(categories []*models.T
|
||||
}
|
||||
|
||||
// GetCategoryNameMapByList returns a transaction category map by a list
|
||||
func (s *TransactionCategoryService) GetCategoryNameMapByList(categories []*models.TransactionCategory) map[string]*models.TransactionCategory {
|
||||
categoryMap := make(map[string]*models.TransactionCategory)
|
||||
func (s *TransactionCategoryService) GetCategoryNameMapByList(categories []*models.TransactionCategory) (expenseCategoryMap map[string]*models.TransactionCategory, incomeCategoryMap map[string]*models.TransactionCategory, transferCategoryMap map[string]*models.TransactionCategory) {
|
||||
expenseCategoryMap = make(map[string]*models.TransactionCategory)
|
||||
incomeCategoryMap = make(map[string]*models.TransactionCategory)
|
||||
transferCategoryMap = make(map[string]*models.TransactionCategory)
|
||||
|
||||
for i := 0; i < len(categories); i++ {
|
||||
category := categories[i]
|
||||
categoryMap[category.Name] = category
|
||||
|
||||
if category.Type == models.CATEGORY_TYPE_INCOME {
|
||||
incomeCategoryMap[category.Name] = category
|
||||
} else if category.Type == models.CATEGORY_TYPE_EXPENSE {
|
||||
expenseCategoryMap[category.Name] = category
|
||||
} else if category.Type == models.CATEGORY_TYPE_TRANSFER {
|
||||
transferCategoryMap[category.Name] = category
|
||||
}
|
||||
return categoryMap
|
||||
}
|
||||
|
||||
return expenseCategoryMap, incomeCategoryMap, transferCategoryMap
|
||||
}
|
||||
|
||||
// GetCategoryNames returns a list with transaction category names from transaction category models list
|
||||
|
||||
Reference in New Issue
Block a user