import payee field as tags when importing a QIF file (#356)

This commit is contained in:
MaysWind
2025-11-25 00:55:36 +08:00
parent de27c8e6c5
commit 9ff1334584
64 changed files with 1353 additions and 871 deletions

View File

@@ -1405,6 +1405,15 @@ func (a *TransactionsApi) TransactionParseImportFileHandler(c *core.WebContext)
fileType := fileTypes[0]
textualOptions := form.Value["options"]
textualOption := ""
if len(textualOptions) > 0 {
textualOption = textualOptions[0]
}
additionalOptions := converter.ParseImporterOptions(textualOption)
var dataImporter converter.TransactionDataImporter
if converters.IsCustomDelimiterSeparatedValuesFileType(fileType) {
@@ -1581,7 +1590,7 @@ func (a *TransactionsApi) TransactionParseImportFileHandler(c *core.WebContext)
tagMap := a.transactionTags.GetVisibleTagNameMapByList(tags)
parsedTransactions, _, _, _, _, _, err := dataImporter.ParseImportedData(c, user, fileData, utcOffset, accountMap, expenseCategoryMap, incomeCategoryMap, transferCategoryMap, tagMap)
parsedTransactions, _, _, _, _, _, err := dataImporter.ParseImportedData(c, user, fileData, utcOffset, additionalOptions, accountMap, expenseCategoryMap, incomeCategoryMap, transferCategoryMap, tagMap)
if err != nil {
log.Errorf(c, "[transactions.TransactionParseImportFileHandler] failed to parse imported data for user \"uid:%d\", because %s", user.Uid, err.Error())

View File

@@ -5,6 +5,7 @@ import (
"time"
"github.com/mayswind/ezbookkeeping/pkg/converters"
"github.com/mayswind/ezbookkeeping/pkg/converters/converter"
"github.com/mayswind/ezbookkeeping/pkg/core"
"github.com/mayswind/ezbookkeeping/pkg/errs"
"github.com/mayswind/ezbookkeeping/pkg/log"
@@ -818,7 +819,7 @@ func (l *UserDataCli) ImportTransaction(c *core.CliContext, username string, fil
return err
}
parsedTransactions, newAccounts, newSubExpenseCategories, newSubIncomeCategories, newSubTransferCategories, newTags, err := dataImporter.ParseImportedData(c, user, data, utils.GetTimezoneOffsetMinutes(time.Local), accountMap, expenseCategoryMap, incomeCategoryMap, transferCategoryMap, tagMap)
parsedTransactions, newAccounts, newSubExpenseCategories, newSubIncomeCategories, newSubTransferCategories, newTags, err := dataImporter.ParseImportedData(c, user, data, utils.GetTimezoneOffsetMinutes(time.Local), converter.DefaultImporterOptions, 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())

View File

@@ -53,7 +53,7 @@ type alipayTransactionDataCsvFileImporter struct {
}
// ParseImportedData returns the imported data by parsing the alipay transaction csv data
func (c *alipayTransactionDataCsvFileImporter) ParseImportedData(ctx core.Context, user *models.User, data []byte, defaultTimezoneOffset int16, accountMap map[string]*models.Account, expenseCategoryMap map[string]map[string]*models.TransactionCategory, incomeCategoryMap map[string]map[string]*models.TransactionCategory, transferCategoryMap map[string]map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionTag, error) {
func (c *alipayTransactionDataCsvFileImporter) ParseImportedData(ctx core.Context, user *models.User, data []byte, defaultTimezoneOffset int16, additionalOptions converter.TransactionDataImporterOptions, accountMap map[string]*models.Account, expenseCategoryMap map[string]map[string]*models.TransactionCategory, incomeCategoryMap map[string]map[string]*models.TransactionCategory, transferCategoryMap map[string]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())
@@ -83,5 +83,5 @@ func (c *alipayTransactionDataCsvFileImporter) ParseImportedData(ctx core.Contex
transactionDataTable := datatable.CreateNewTransactionDataTableFromCommonDataTable(commonDataTable, alipayTransactionSupportedColumns, transactionRowParser)
dataTableImporter := converter.CreateNewSimpleImporterWithTypeNameMapping(alipayTransactionTypeNameMapping)
return dataTableImporter.ParseImportedData(ctx, user, transactionDataTable, defaultTimezoneOffset, accountMap, expenseCategoryMap, incomeCategoryMap, transferCategoryMap, tagMap)
return dataTableImporter.ParseImportedData(ctx, user, transactionDataTable, defaultTimezoneOffset, additionalOptions, accountMap, expenseCategoryMap, incomeCategoryMap, transferCategoryMap, tagMap)
}

View File

@@ -8,6 +8,7 @@ import (
"golang.org/x/text/encoding/simplifiedchinese"
"github.com/mayswind/ezbookkeeping/pkg/converters/converter"
"github.com/mayswind/ezbookkeeping/pkg/core"
"github.com/mayswind/ezbookkeeping/pkg/errs"
"github.com/mayswind/ezbookkeeping/pkg/models"
@@ -15,7 +16,7 @@ import (
)
func TestAlipayCsvFileImporterParseImportedData_MinimumValidData(t *testing.T) {
converter := AlipayWebTransactionDataCsvFileImporter
importer := AlipayWebTransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -35,7 +36,7 @@ func TestAlipayCsvFileImporterParseImportedData_MinimumValidData(t *testing.T) {
"------------------------------------------------------------------------------------\n")
assert.Nil(t, err)
allNewTransactions, allNewAccounts, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, allNewTags, err := converter.ParseImportedData(context, user, []byte(data), 0, nil, nil, nil, nil, nil)
allNewTransactions, allNewAccounts, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, allNewTags, err := importer.ParseImportedData(context, user, []byte(data), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 4, len(allNewTransactions))
@@ -94,7 +95,7 @@ func TestAlipayCsvFileImporterParseImportedData_MinimumValidData(t *testing.T) {
}
func TestAlipayCsvFileImporterParseImportedData_ParseRefundTransaction(t *testing.T) {
converter := AlipayWebTransactionDataCsvFileImporter
importer := AlipayWebTransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -112,7 +113,7 @@ func TestAlipayCsvFileImporterParseImportedData_ParseRefundTransaction(t *testin
"------------------------------------------------------------------------------------\n")
assert.Nil(t, err)
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(data1), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(data1), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, int64(1234567890), allNewTransactions[0].Uid)
@@ -132,7 +133,7 @@ func TestAlipayCsvFileImporterParseImportedData_ParseRefundTransaction(t *testin
"------------------------------------------------------------------------------------\n")
assert.Nil(t, err)
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data2), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(data2), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, int64(1234567890), allNewTransactions[0].Uid)
@@ -144,7 +145,7 @@ func TestAlipayCsvFileImporterParseImportedData_ParseRefundTransaction(t *testin
}
func TestAlipayCsvFileImporterParseImportedData_ParseInvestmentRefundTransaction(t *testing.T) {
converter := AlipayAppTransactionDataCsvFileImporter
importer := AlipayAppTransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -163,7 +164,7 @@ func TestAlipayCsvFileImporterParseImportedData_ParseInvestmentRefundTransaction
"2024-09-01 01:00:00,Test Account2,xxx-买入,不计收支,0.01,Test Account,退款成功,\n" +
"2024-09-01 02:00:00,Test Account2,xxx-买入退款,不计收支,0.01,Test Account,退款成功,\n")
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(data1), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(data1), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 2, len(allNewTransactions))
@@ -184,7 +185,7 @@ func TestAlipayCsvFileImporterParseImportedData_ParseInvestmentRefundTransaction
}
func TestAlipayCsvFileImporterParseImportedData_ParseInvalidTime(t *testing.T) {
converter := AlipayWebTransactionDataCsvFileImporter
importer := AlipayWebTransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -201,7 +202,7 @@ func TestAlipayCsvFileImporterParseImportedData_ParseInvalidTime(t *testing.T) {
"------------------------------------------------------------------------------------\n")
assert.Nil(t, err)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data1), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(data1), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrTransactionTimeInvalid.Message)
data2, err := simplifiedchinese.GB18030.NewEncoder().String("支付宝交易记录明细查询\n" +
@@ -213,12 +214,12 @@ func TestAlipayCsvFileImporterParseImportedData_ParseInvalidTime(t *testing.T) {
"------------------------------------------------------------------------------------\n")
assert.Nil(t, err)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data2), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(data2), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrTransactionTimeInvalid.Message)
}
func TestAlipayCsvFileImporterParseImportedData_ParseInvalidType(t *testing.T) {
converter := AlipayWebTransactionDataCsvFileImporter
importer := AlipayWebTransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -235,12 +236,12 @@ func TestAlipayCsvFileImporterParseImportedData_ParseInvalidType(t *testing.T) {
"------------------------------------------------------------------------------------\n")
assert.Nil(t, err)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(data), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrNotFoundTransactionDataInFile.Message)
}
func TestAlipayCsvFileImporterParseImportedData_ParseAccountName(t *testing.T) {
converter := AlipayWebTransactionDataCsvFileImporter
importer := AlipayWebTransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -258,7 +259,7 @@ func TestAlipayCsvFileImporterParseImportedData_ParseAccountName(t *testing.T) {
"------------------------------------------------------------------------------------\n")
assert.Nil(t, err)
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(data1), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(data1), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
@@ -274,7 +275,7 @@ func TestAlipayCsvFileImporterParseImportedData_ParseAccountName(t *testing.T) {
"------------------------------------------------------------------------------------\n")
assert.Nil(t, err)
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data2), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(data2), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
@@ -290,7 +291,7 @@ func TestAlipayCsvFileImporterParseImportedData_ParseAccountName(t *testing.T) {
"------------------------------------------------------------------------------------\n")
assert.Nil(t, err)
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data3), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(data3), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
@@ -307,7 +308,7 @@ func TestAlipayCsvFileImporterParseImportedData_ParseAccountName(t *testing.T) {
"------------------------------------------------------------------------------------\n")
assert.Nil(t, err)
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data4), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(data4), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
@@ -324,7 +325,7 @@ func TestAlipayCsvFileImporterParseImportedData_ParseAccountName(t *testing.T) {
"------------------------------------------------------------------------------------\n")
assert.Nil(t, err)
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data5), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(data5), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
@@ -341,7 +342,7 @@ func TestAlipayCsvFileImporterParseImportedData_ParseAccountName(t *testing.T) {
"------------------------------------------------------------------------------------\n")
assert.Nil(t, err)
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data6), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(data6), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
@@ -358,7 +359,7 @@ func TestAlipayCsvFileImporterParseImportedData_ParseAccountName(t *testing.T) {
"------------------------------------------------------------------------------------\n")
assert.Nil(t, err)
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data7), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(data7), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
@@ -367,7 +368,7 @@ func TestAlipayCsvFileImporterParseImportedData_ParseAccountName(t *testing.T) {
}
func TestAlipayCsvFileImporterParseImportedData_ParseCategory(t *testing.T) {
converter := AlipayAppTransactionDataCsvFileImporter
importer := AlipayAppTransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -388,7 +389,7 @@ func TestAlipayCsvFileImporterParseImportedData_ParseCategory(t *testing.T) {
"2024-09-01 23:59:59,Test Category3,充值-普通充值,不计收支,0.05,交易成功,\n")
assert.Nil(t, err)
allNewTransactions, _, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, _, err := converter.ParseImportedData(context, user, []byte(data1), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, _, err := importer.ParseImportedData(context, user, []byte(data1), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 3, len(allNewTransactions))
@@ -407,7 +408,7 @@ func TestAlipayCsvFileImporterParseImportedData_ParseCategory(t *testing.T) {
}
func TestAlipayCsvFileImporterParseImportedData_ParseRelatedAccount(t *testing.T) {
converter := AlipayAppTransactionDataCsvFileImporter
importer := AlipayAppTransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -434,7 +435,7 @@ func TestAlipayCsvFileImporterParseImportedData_ParseRelatedAccount(t *testing.T
"2024-09-01 08:00:00,Test Account4,信用卡还款,不计收支,0.01,Test Account,还款成功,repayment,\n")
assert.Nil(t, err)
allNewTransactions, allNewAccounts, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(data1), 0, nil, nil, nil, nil, nil)
allNewTransactions, allNewAccounts, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(data1), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 9, len(allNewTransactions))
@@ -529,7 +530,7 @@ func TestAlipayCsvFileImporterParseImportedData_ParseRelatedAccount(t *testing.T
}
func TestAlipayCsvFileImporterParseImportedData_ParseDescription(t *testing.T) {
converter := AlipayWebTransactionDataCsvFileImporter
importer := AlipayWebTransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -546,7 +547,7 @@ func TestAlipayCsvFileImporterParseImportedData_ParseDescription(t *testing.T) {
"------------------------------------------------------------------------------------\n")
assert.Nil(t, err)
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(data1), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(data1), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
@@ -561,7 +562,7 @@ func TestAlipayCsvFileImporterParseImportedData_ParseDescription(t *testing.T) {
"------------------------------------------------------------------------------------\n")
assert.Nil(t, err)
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data2), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(data2), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
@@ -569,7 +570,7 @@ func TestAlipayCsvFileImporterParseImportedData_ParseDescription(t *testing.T) {
}
func TestAlipayCsvFileImporterParseImportedData_SkipClosedIncomeOrTransferTransaction(t *testing.T) {
converter := AlipayWebTransactionDataCsvFileImporter
importer := AlipayWebTransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -586,12 +587,12 @@ func TestAlipayCsvFileImporterParseImportedData_SkipClosedIncomeOrTransferTransa
"2024-09-01 23:59:59 ,充值-普通充值 ,0.05 ,不计收支 ,交易关闭 ,\n" +
"------------------------------------------------------------------------------------\n")
assert.Nil(t, err)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(data), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrNotFoundTransactionDataInFile.Message)
}
func TestAlipayCsvFileImporterParseImportedData_SkipUnknownProductTransferTransaction(t *testing.T) {
converter := AlipayWebTransactionDataCsvFileImporter
importer := AlipayWebTransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -607,12 +608,12 @@ func TestAlipayCsvFileImporterParseImportedData_SkipUnknownProductTransferTransa
"2024-09-01 23:59:59 ,xxxx ,0.05 ,不计收支 ,交易成功 ,\n" +
"------------------------------------------------------------------------------------\n")
assert.Nil(t, err)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(data), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrNotFoundTransactionDataInFile.Message)
}
func TestAlipayCsvFileImporterParseImportedData_SkipUnknownStatusTransaction(t *testing.T) {
converter := AlipayWebTransactionDataCsvFileImporter
importer := AlipayWebTransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -628,12 +629,12 @@ func TestAlipayCsvFileImporterParseImportedData_SkipUnknownStatusTransaction(t *
"2024-09-01 01:23:45 ,xxxx ,0.12 ,收入 ,xxxx ,\n" +
"------------------------------------------------------------------------------------\n")
assert.Nil(t, err)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(data), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrNotFoundTransactionDataInFile.Message)
}
func TestAlipayCsvFileImporterParseImportedData_MissingFileHeader(t *testing.T) {
converter := AlipayWebTransactionDataCsvFileImporter
importer := AlipayWebTransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -647,15 +648,15 @@ func TestAlipayCsvFileImporterParseImportedData_MissingFileHeader(t *testing.T)
"------------------------------------------------------------------------------------\n")
assert.Nil(t, err)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(data), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrInvalidFileHeader.Message)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(""), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(""), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrInvalidFileHeader.Message)
}
func TestAlipayCsvFileImporterParseImportedData_MissingRequiredColumn(t *testing.T) {
converter := AlipayWebTransactionDataCsvFileImporter
importer := AlipayWebTransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -671,7 +672,7 @@ func TestAlipayCsvFileImporterParseImportedData_MissingRequiredColumn(t *testing
"金额(元),收/支 ,交易状态 ,\n" +
"0.12 ,收入 ,交易成功 ,\n" +
"------------------------------------------------------------------------------------\n")
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data1), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(data1), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrMissingRequiredFieldInHeaderRow.Message)
// Missing Amount Column
@@ -682,7 +683,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, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(data2), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrMissingRequiredFieldInHeaderRow.Message)
// Missing Status Column
@@ -693,7 +694,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, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(data3), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrMissingRequiredFieldInHeaderRow.Message)
// Missing Type Column
@@ -704,12 +705,12 @@ 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, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(data4), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrMissingRequiredFieldInHeaderRow.Message)
}
func TestAlipayCsvFileImporterParseImportedData_NoTransactionData(t *testing.T) {
converter := AlipayWebTransactionDataCsvFileImporter
importer := AlipayWebTransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -723,6 +724,6 @@ func TestAlipayCsvFileImporterParseImportedData_NoTransactionData(t *testing.T)
"---------------------------------交易记录明细列表------------------------------------\n" +
"交易创建时间 ,金额(元),收/支 ,交易状态 ,\n" +
"------------------------------------------------------------------------------------\n")
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data1), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(data1), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrNotFoundTransactionDataInFile.Message)
}

View File

@@ -24,7 +24,7 @@ var (
)
// ParseImportedData returns the imported data by parsing the Beancount transaction data
func (c *beancountTransactionDataImporter) ParseImportedData(ctx core.Context, user *models.User, data []byte, defaultTimezoneOffset int16, accountMap map[string]*models.Account, expenseCategoryMap map[string]map[string]*models.TransactionCategory, incomeCategoryMap map[string]map[string]*models.TransactionCategory, transferCategoryMap map[string]map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionTag, error) {
func (c *beancountTransactionDataImporter) ParseImportedData(ctx core.Context, user *models.User, data []byte, defaultTimezoneOffset int16, additionalOptions converter.TransactionDataImporterOptions, accountMap map[string]*models.Account, expenseCategoryMap map[string]map[string]*models.TransactionCategory, incomeCategoryMap map[string]map[string]*models.TransactionCategory, transferCategoryMap map[string]map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionTag, error) {
beancountDataReader, err := createNewBeancountDataReader(ctx, data)
if err != nil {
@@ -45,5 +45,5 @@ func (c *beancountTransactionDataImporter) ParseImportedData(ctx core.Context, u
dataTableImporter := converter.CreateNewImporterWithTypeNameMapping(beancountTransactionTypeNameMapping, "", "", BEANCOUNT_TRANSACTION_TAG_SEPARATOR)
return dataTableImporter.ParseImportedData(ctx, user, transactionDataTable, defaultTimezoneOffset, accountMap, expenseCategoryMap, incomeCategoryMap, transferCategoryMap, tagMap)
return dataTableImporter.ParseImportedData(ctx, user, transactionDataTable, defaultTimezoneOffset, additionalOptions, accountMap, expenseCategoryMap, incomeCategoryMap, transferCategoryMap, tagMap)
}

View File

@@ -5,6 +5,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/mayswind/ezbookkeeping/pkg/converters/converter"
"github.com/mayswind/ezbookkeeping/pkg/core"
"github.com/mayswind/ezbookkeeping/pkg/errs"
"github.com/mayswind/ezbookkeeping/pkg/models"
@@ -12,7 +13,7 @@ import (
)
func TestBeancountTransactionDataFileParseImportedData_MinimumValidData(t *testing.T) {
converter := BeancountTransactionDataImporter
importer := BeancountTransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -20,7 +21,7 @@ func TestBeancountTransactionDataFileParseImportedData_MinimumValidData(t *testi
DefaultCurrency: "CNY",
}
allNewTransactions, allNewAccounts, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, allNewTags, err := converter.ParseImportedData(context, user, []byte(
allNewTransactions, allNewAccounts, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, allNewTags, err := importer.ParseImportedData(context, user, []byte(
"2024-09-01 *\n"+
" Equity:Opening-Balances -123.45 CNY\n"+
" Assets:TestAccount 123.45 CNY\n"+
@@ -32,7 +33,7 @@ func TestBeancountTransactionDataFileParseImportedData_MinimumValidData(t *testi
" Expenses:TestCategory2 1.00 CNY\n"+
"2024-09-04 *\n"+
" Assets:TestAccount -0.05 CNY\n"+
" Assets:TestAccount2 0.05 CNY\n"), 0, nil, nil, nil, nil, nil)
" Assets:TestAccount2 0.05 CNY\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
@@ -91,7 +92,7 @@ func TestBeancountTransactionDataFileParseImportedData_MinimumValidData(t *testi
}
func TestBeancountTransactionDataFileParseImportedData_MinimumValidData2(t *testing.T) {
converter := BeancountTransactionDataImporter
importer := BeancountTransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -99,7 +100,7 @@ func TestBeancountTransactionDataFileParseImportedData_MinimumValidData2(t *test
DefaultCurrency: "CNY",
}
allNewTransactions, allNewAccounts, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, allNewTags, err := converter.ParseImportedData(context, user, []byte(
allNewTransactions, allNewAccounts, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, allNewTags, err := importer.ParseImportedData(context, user, []byte(
"2024-09-01 *\n"+
" Assets:TestAccount 123.45 CNY\n"+
" Equity:Opening-Balances -123.45 CNY\n"+
@@ -111,7 +112,7 @@ func TestBeancountTransactionDataFileParseImportedData_MinimumValidData2(t *test
" Assets:TestAccount -1.00 CNY\n"+
"2024-09-04 *\n"+
" Assets:TestAccount2 0.05 CNY\n"+
" Assets:TestAccount -0.05 CNY\n"), 0, nil, nil, nil, nil, nil)
" Assets:TestAccount -0.05 CNY\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
@@ -170,7 +171,7 @@ func TestBeancountTransactionDataFileParseImportedData_MinimumValidData2(t *test
}
func TestBeancountTransactionDataFileParseImportedData_ParseInvalidTime(t *testing.T) {
converter := BeancountTransactionDataImporter
importer := BeancountTransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -178,15 +179,15 @@ func TestBeancountTransactionDataFileParseImportedData_ParseInvalidTime(t *testi
DefaultCurrency: "CNY",
}
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"2024/09/01 *\n"+
" Equity:Opening-Balances -123.45 CNY\n"+
" Assets:TestAccount 123.45 CNY\n"), 0, nil, nil, nil, nil, nil)
" Assets:TestAccount 123.45 CNY\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrNotFoundTransactionDataInFile.Message)
}
func TestBeancountTransactionDataFileParseImportedData_ParseValidCurrency(t *testing.T) {
converter := BeancountTransactionDataImporter
importer := BeancountTransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -194,10 +195,10 @@ func TestBeancountTransactionDataFileParseImportedData_ParseValidCurrency(t *tes
DefaultCurrency: "CNY",
}
allNewTransactions, allNewAccounts, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
allNewTransactions, allNewAccounts, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"2024-09-01 * \"Payee Name\" \"Hello\nWorld\"\n"+
" Assets:TestAccount -0.12 USD\n"+
" Assets:TestAccount2 0.84 CNY\n"), 0, nil, nil, nil, nil, nil)
" Assets:TestAccount2 0.84 CNY\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
@@ -222,7 +223,7 @@ func TestBeancountTransactionDataFileParseImportedData_ParseValidCurrency(t *tes
}
func TestBeancountTransactionDataFileParseImportedData_ParseInvalidAmount(t *testing.T) {
converter := BeancountTransactionDataImporter
importer := BeancountTransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -230,21 +231,21 @@ func TestBeancountTransactionDataFileParseImportedData_ParseInvalidAmount(t *tes
DefaultCurrency: "CNY",
}
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"2024-09-01 *\n"+
" Equity:Opening-Balances -abc CNY\n"+
" Assets:TestAccount abc CNY\n"), 0, nil, nil, nil, nil, nil)
" Assets:TestAccount abc CNY\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrAmountInvalid.Message)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"2024-09-01 *\n"+
" Equity:Opening-Balances -1/0 CNY\n"+
" Assets:TestAccount 1/0 CNY\n"), 0, nil, nil, nil, nil, nil)
" Assets:TestAccount 1/0 CNY\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrAmountInvalid.Message)
}
func TestBeancountTransactionDataFileParseImportedData_ParseDescription(t *testing.T) {
converter := BeancountTransactionDataImporter
importer := BeancountTransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -252,13 +253,13 @@ func TestBeancountTransactionDataFileParseImportedData_ParseDescription(t *testi
DefaultCurrency: "CNY",
}
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"2024-09-01 * \"foo bar\t#test\n\"\n"+
" Equity:Opening-Balances -123.45 CNY\n"+
" Assets:TestAccount 123.45 CNY\n"+
"2024-09-02 * \"Payee Name\" \"Hello\nWorld\"\n"+
" Income:TestCategory -0.12 CNY\n"+
" Assets:TestAccount 0.12 CNY\n"), 0, nil, nil, nil, nil, nil)
" Assets:TestAccount 0.12 CNY\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
@@ -269,7 +270,7 @@ func TestBeancountTransactionDataFileParseImportedData_ParseDescription(t *testi
}
func TestBeancountTransactionDataFileParseImportedData_InvalidTransaction(t *testing.T) {
converter := BeancountTransactionDataImporter
importer := BeancountTransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -277,33 +278,33 @@ func TestBeancountTransactionDataFileParseImportedData_InvalidTransaction(t *tes
DefaultCurrency: "CNY",
}
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"2024-09-02 * \"Payee Name\" \"Hello\nWorld\"\n"+
" Assets:TestAccount 0.11 CNY\n"+
" Assets:TestAccount2 0.11 CNY\n"), 0, nil, nil, nil, nil, nil)
" Assets:TestAccount2 0.11 CNY\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrInvalidBeancountFile.Message)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"2024-09-02 * \"Payee Name\" \"Hello\nWorld\"\n"+
" Expenses:TestCategory -0.11 CNY\n"+
" Expenses:TestCategory2 0.11 CNY\n"), 0, nil, nil, nil, nil, nil)
" Expenses:TestCategory2 0.11 CNY\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrThereAreNotSupportedTransactionType.Message)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"2024-09-02 * \"Payee Name\" \"Hello\nWorld\"\n"+
" Income:TestCategory -0.11 CNY\n"+
" Income:TestCategory2 0.11 CNY\n"), 0, nil, nil, nil, nil, nil)
" Income:TestCategory2 0.11 CNY\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrThereAreNotSupportedTransactionType.Message)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"2024-09-02 * \"Payee Name\" \"Hello\nWorld\"\n"+
" Equity:TestCategory -0.11 CNY\n"+
" Equity:TestCategory2 0.11 CNY\n"), 0, nil, nil, nil, nil, nil)
" Equity:TestCategory2 0.11 CNY\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrThereAreNotSupportedTransactionType.Message)
}
func TestBeancountTransactionDataFileParseImportedData_NotSupportedToParseSplitTransaction(t *testing.T) {
converter := BeancountTransactionDataImporter
importer := BeancountTransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -311,16 +312,16 @@ func TestBeancountTransactionDataFileParseImportedData_NotSupportedToParseSplitT
DefaultCurrency: "CNY",
}
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"2024-09-02 * \"Payee Name\" \"Hello\nWorld\"\n"+
" Assets:TestAccount -0.23 CNY\n"+
" Assets:TestAccount2 0.11 CNY\n"+
" Assets:TestAccount3 0.12 CNY\n"), 0, nil, nil, nil, nil, nil)
" Assets:TestAccount3 0.12 CNY\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrNotSupportedSplitTransactions.Message)
}
func TestBeancountTransactionDataFileParseImportedData_MissingTransactionRequiredData(t *testing.T) {
converter := BeancountTransactionDataImporter
importer := BeancountTransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -329,30 +330,30 @@ func TestBeancountTransactionDataFileParseImportedData_MissingTransactionRequire
}
// Missing Transaction Time
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"* \"narration\"\n"+
" Equity:Opening-Balances -123.45 CNY\n"+
" Assets:TestAccount 123.45 CNY\n"), 0, nil, nil, nil, nil, nil)
" Assets:TestAccount 123.45 CNY\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrNotFoundTransactionDataInFile.Message)
// Missing Account Name
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"2024-09-01 * \"narration\"\n"+
" Equity:Opening-Balances -123.45 CNY\n"+
" 123.45 CNY\n"), 0, nil, nil, nil, nil, nil)
" 123.45 CNY\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrInvalidBeancountFile.Message)
// Missing Amount
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"2024-09-01 * \"narration\"\n"+
" Equity:Opening-Balances\n"+
" Assets:TestAccount\n"), 0, nil, nil, nil, nil, nil)
" Assets:TestAccount\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrInvalidBeancountFile.Message)
// Missing Commodity
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"2024-09-01 * \"narration\"\n"+
" Equity:Opening-Balances -123.45\n"+
" Assets:TestAccount 123.45\n"), 0, nil, nil, nil, nil, nil)
" Assets:TestAccount 123.45\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrInvalidBeancountFile.Message)
}

View File

@@ -23,7 +23,7 @@ var (
)
// ParseImportedData returns the imported data by parsing the camt.053 file transaction data
func (c *camt053TransactionDataImporter) ParseImportedData(ctx core.Context, user *models.User, data []byte, defaultTimezoneOffset int16, accountMap map[string]*models.Account, expenseCategoryMap map[string]map[string]*models.TransactionCategory, incomeCategoryMap map[string]map[string]*models.TransactionCategory, transferCategoryMap map[string]map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionTag, error) {
func (c *camt053TransactionDataImporter) ParseImportedData(ctx core.Context, user *models.User, data []byte, defaultTimezoneOffset int16, additionalOptions converter.TransactionDataImporterOptions, accountMap map[string]*models.Account, expenseCategoryMap map[string]map[string]*models.TransactionCategory, incomeCategoryMap map[string]map[string]*models.TransactionCategory, transferCategoryMap map[string]map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionTag, error) {
camt053DataReader, err := createNewCamt053FileReader(data)
if err != nil {
@@ -44,5 +44,5 @@ func (c *camt053TransactionDataImporter) ParseImportedData(ctx core.Context, use
dataTableImporter := converter.CreateNewSimpleImporterWithTypeNameMapping(camtTransactionTypeNameMapping)
return dataTableImporter.ParseImportedData(ctx, user, transactionDataTable, defaultTimezoneOffset, accountMap, expenseCategoryMap, incomeCategoryMap, transferCategoryMap, tagMap)
return dataTableImporter.ParseImportedData(ctx, user, transactionDataTable, defaultTimezoneOffset, additionalOptions, accountMap, expenseCategoryMap, incomeCategoryMap, transferCategoryMap, tagMap)
}

View File

@@ -5,6 +5,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/mayswind/ezbookkeeping/pkg/converters/converter"
"github.com/mayswind/ezbookkeeping/pkg/core"
"github.com/mayswind/ezbookkeeping/pkg/errs"
"github.com/mayswind/ezbookkeeping/pkg/models"
@@ -12,7 +13,7 @@ import (
)
func TestCamt053TransactionDataFileParseImportedData_MinimumValidData(t *testing.T) {
converter := Camt053TransactionDataImporter
importer := Camt053TransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -20,7 +21,7 @@ func TestCamt053TransactionDataFileParseImportedData_MinimumValidData(t *testing
DefaultCurrency: "CNY",
}
allNewTransactions, allNewAccounts, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, allNewTags, err := converter.ParseImportedData(context, user, []byte(
allNewTransactions, allNewAccounts, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, allNewTags, err := importer.ParseImportedData(context, user, []byte(
`<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:camt.053.001.02">
<BkToCstmrStmt>
@@ -64,7 +65,7 @@ func TestCamt053TransactionDataFileParseImportedData_MinimumValidData(t *testing
</Ntry>
</Stmt>
</BkToCstmrStmt>
</Document>`), 0, nil, nil, nil, nil, nil)
</Document>`), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
@@ -115,7 +116,7 @@ func TestCamt053TransactionDataFileParseImportedData_MinimumValidData(t *testing
}
func TestCamt053TransactionDataFileParseImportedData_ParseValidTransactionTime(t *testing.T) {
converter := Camt053TransactionDataImporter
importer := Camt053TransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -123,7 +124,7 @@ func TestCamt053TransactionDataFileParseImportedData_ParseValidTransactionTime(t
DefaultCurrency: "CNY",
}
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
`<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:camt.053.001.02">
<BkToCstmrStmt>
@@ -157,7 +158,7 @@ func TestCamt053TransactionDataFileParseImportedData_ParseValidTransactionTime(t
</Ntry>
</Stmt>
</BkToCstmrStmt>
</Document>`), 0, nil, nil, nil, nil, nil)
</Document>`), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 3, len(allNewTransactions))
@@ -168,7 +169,7 @@ func TestCamt053TransactionDataFileParseImportedData_ParseValidTransactionTime(t
}
func TestCamt053TransactionDataFileParseImportedData_ParseInvalidTransactionTime(t *testing.T) {
converter := Camt053TransactionDataImporter
importer := Camt053TransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -176,7 +177,7 @@ func TestCamt053TransactionDataFileParseImportedData_ParseInvalidTransactionTime
DefaultCurrency: "CNY",
}
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
`<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:camt.053.001.02">
<BkToCstmrStmt>
@@ -196,10 +197,10 @@ func TestCamt053TransactionDataFileParseImportedData_ParseInvalidTransactionTime
</Ntry>
</Stmt>
</BkToCstmrStmt>
</Document>`), 0, nil, nil, nil, nil, nil)
</Document>`), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrTransactionTimeInvalid.Message)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
`<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:camt.053.001.02">
<BkToCstmrStmt>
@@ -219,10 +220,10 @@ func TestCamt053TransactionDataFileParseImportedData_ParseInvalidTransactionTime
</Ntry>
</Stmt>
</BkToCstmrStmt>
</Document>`), 0, nil, nil, nil, nil, nil)
</Document>`), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrTransactionTimeInvalid.Message)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
`<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:camt.053.001.02">
<BkToCstmrStmt>
@@ -242,10 +243,10 @@ func TestCamt053TransactionDataFileParseImportedData_ParseInvalidTransactionTime
</Ntry>
</Stmt>
</BkToCstmrStmt>
</Document>`), 0, nil, nil, nil, nil, nil)
</Document>`), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrTransactionTimeInvalid.Message)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
`<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:camt.053.001.02">
<BkToCstmrStmt>
@@ -265,12 +266,12 @@ func TestCamt053TransactionDataFileParseImportedData_ParseInvalidTransactionTime
</Ntry>
</Stmt>
</BkToCstmrStmt>
</Document>`), 0, nil, nil, nil, nil, nil)
</Document>`), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrTransactionTimeInvalid.Message)
}
func TestCamt053TransactionDataFileParseImportedData_ParseTransactionValidAmountAndCurrency(t *testing.T) {
converter := Camt053TransactionDataImporter
importer := Camt053TransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -278,7 +279,7 @@ func TestCamt053TransactionDataFileParseImportedData_ParseTransactionValidAmount
DefaultCurrency: "CNY",
}
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
`<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:camt.053.001.02">
<BkToCstmrStmt>
@@ -314,7 +315,7 @@ func TestCamt053TransactionDataFileParseImportedData_ParseTransactionValidAmount
</Ntry>
</Stmt>
</BkToCstmrStmt>
</Document>`), 0, nil, nil, nil, nil, nil)
</Document>`), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 2, len(allNewTransactions))
@@ -323,7 +324,7 @@ func TestCamt053TransactionDataFileParseImportedData_ParseTransactionValidAmount
assert.Equal(t, "USD", allNewTransactions[1].OriginalSourceAccountCurrency)
assert.Equal(t, int64(10023), allNewTransactions[1].Amount)
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
`<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:camt.053.001.02">
<BkToCstmrStmt>
@@ -365,7 +366,7 @@ func TestCamt053TransactionDataFileParseImportedData_ParseTransactionValidAmount
</Ntry>
</Stmt>
</BkToCstmrStmt>
</Document>`), 0, nil, nil, nil, nil, nil)
</Document>`), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 2, len(allNewTransactions))
@@ -374,7 +375,7 @@ func TestCamt053TransactionDataFileParseImportedData_ParseTransactionValidAmount
assert.Equal(t, "USD", allNewTransactions[1].OriginalSourceAccountCurrency)
assert.Equal(t, int64(9999), allNewTransactions[1].Amount)
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
`<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:camt.053.001.02">
<BkToCstmrStmt>
@@ -403,14 +404,14 @@ func TestCamt053TransactionDataFileParseImportedData_ParseTransactionValidAmount
</Ntry>
</Stmt>
</BkToCstmrStmt>
</Document>`), 0, nil, nil, nil, nil, nil)
</Document>`), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
assert.Equal(t, "USD", allNewTransactions[0].OriginalSourceAccountCurrency)
assert.Equal(t, int64(12345), allNewTransactions[0].Amount)
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
`<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:camt.053.001.02">
<BkToCstmrStmt>
@@ -430,7 +431,7 @@ func TestCamt053TransactionDataFileParseImportedData_ParseTransactionValidAmount
</Ntry>
</Stmt>
</BkToCstmrStmt>
</Document>`), 0, nil, nil, nil, nil, nil)
</Document>`), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
@@ -439,7 +440,7 @@ func TestCamt053TransactionDataFileParseImportedData_ParseTransactionValidAmount
}
func TestCamt053TransactionDataFileParseImportedData_ParseTransactionInvalidAmountAndCurrency(t *testing.T) {
converter := Camt053TransactionDataImporter
importer := Camt053TransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -447,7 +448,7 @@ func TestCamt053TransactionDataFileParseImportedData_ParseTransactionInvalidAmou
DefaultCurrency: "CNY",
}
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
`<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:camt.053.001.02">
<BkToCstmrStmt>
@@ -467,10 +468,10 @@ func TestCamt053TransactionDataFileParseImportedData_ParseTransactionInvalidAmou
</Ntry>
</Stmt>
</BkToCstmrStmt>
</Document>`), 0, nil, nil, nil, nil, nil)
</Document>`), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrAmountInvalid.Message)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
`<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:camt.053.001.02">
<BkToCstmrStmt>
@@ -498,10 +499,10 @@ func TestCamt053TransactionDataFileParseImportedData_ParseTransactionInvalidAmou
</Ntry>
</Stmt>
</BkToCstmrStmt>
</Document>`), 0, nil, nil, nil, nil, nil)
</Document>`), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrAmountInvalid.Message)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
`<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:camt.053.001.02">
<BkToCstmrStmt>
@@ -529,12 +530,12 @@ func TestCamt053TransactionDataFileParseImportedData_ParseTransactionInvalidAmou
</Ntry>
</Stmt>
</BkToCstmrStmt>
</Document>`), 0, nil, nil, nil, nil, nil)
</Document>`), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrAmountInvalid.Message)
}
func TestCamt053TransactionDataFileParseImportedData_ParseDescription(t *testing.T) {
converter := Camt053TransactionDataImporter
importer := Camt053TransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -542,7 +543,7 @@ func TestCamt053TransactionDataFileParseImportedData_ParseDescription(t *testing
DefaultCurrency: "CNY",
}
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
`<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:camt.053.001.02">
<BkToCstmrStmt>
@@ -572,13 +573,13 @@ func TestCamt053TransactionDataFileParseImportedData_ParseDescription(t *testing
</Ntry>
</Stmt>
</BkToCstmrStmt>
</Document>`), 0, nil, nil, nil, nil, nil)
</Document>`), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
assert.Equal(t, "Test Transaction", allNewTransactions[0].Comment)
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
`<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:camt.053.001.02">
<BkToCstmrStmt>
@@ -607,13 +608,13 @@ func TestCamt053TransactionDataFileParseImportedData_ParseDescription(t *testing
</Ntry>
</Stmt>
</BkToCstmrStmt>
</Document>`), 0, nil, nil, nil, nil, nil)
</Document>`), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
assert.Equal(t, "Test Line 1\nTest Line 2", allNewTransactions[0].Comment)
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
`<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:camt.053.001.02">
<BkToCstmrStmt>
@@ -634,7 +635,7 @@ func TestCamt053TransactionDataFileParseImportedData_ParseDescription(t *testing
</Ntry>
</Stmt>
</BkToCstmrStmt>
</Document>`), 0, nil, nil, nil, nil, nil)
</Document>`), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
@@ -642,7 +643,7 @@ func TestCamt053TransactionDataFileParseImportedData_ParseDescription(t *testing
}
func TestCamt053TransactionDataFileParseImportedData_MissingAccountNode(t *testing.T) {
converter := Camt053TransactionDataImporter
importer := Camt053TransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -650,7 +651,7 @@ func TestCamt053TransactionDataFileParseImportedData_MissingAccountNode(t *testi
DefaultCurrency: "CNY",
}
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
`<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:camt.053.001.02">
<BkToCstmrStmt>
@@ -664,12 +665,12 @@ func TestCamt053TransactionDataFileParseImportedData_MissingAccountNode(t *testi
</Ntry>
</Stmt>
</BkToCstmrStmt>
</Document>`), 0, nil, nil, nil, nil, nil)
</Document>`), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrMissingAccountData.Message)
}
func TestCamt053TransactionDataFileParseImportedData_MissingTransactionRequiredNode(t *testing.T) {
converter := Camt053TransactionDataImporter
importer := Camt053TransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -677,7 +678,7 @@ func TestCamt053TransactionDataFileParseImportedData_MissingTransactionRequiredN
DefaultCurrency: "CNY",
}
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
`<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:camt.053.001.02">
<BkToCstmrStmt>
@@ -694,10 +695,10 @@ func TestCamt053TransactionDataFileParseImportedData_MissingTransactionRequiredN
</Ntry>
</Stmt>
</BkToCstmrStmt>
</Document>`), 0, nil, nil, nil, nil, nil)
</Document>`), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrMissingTransactionTime.Message)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
`<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:camt.053.001.02">
<BkToCstmrStmt>
@@ -716,10 +717,10 @@ func TestCamt053TransactionDataFileParseImportedData_MissingTransactionRequiredN
</Ntry>
</Stmt>
</BkToCstmrStmt>
</Document>`), 0, nil, nil, nil, nil, nil)
</Document>`), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrTransactionTypeInvalid.Message)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
`<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:camt.053.001.02">
<BkToCstmrStmt>
@@ -738,10 +739,10 @@ func TestCamt053TransactionDataFileParseImportedData_MissingTransactionRequiredN
</Ntry>
</Stmt>
</BkToCstmrStmt>
</Document>`), 0, nil, nil, nil, nil, nil)
</Document>`), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrAmountInvalid.Message)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
`<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:camt.053.001.02">
<BkToCstmrStmt>
@@ -760,6 +761,6 @@ func TestCamt053TransactionDataFileParseImportedData_MissingTransactionRequiredN
</Ntry>
</Stmt>
</BkToCstmrStmt>
</Document>`), 0, nil, nil, nil, nil, nil)
</Document>`), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrAccountCurrencyInvalid.Message)
}

View File

@@ -29,7 +29,7 @@ type DataTableTransactionDataImporter struct {
}
// ParseImportedData returns the imported transaction data
func (c *DataTableTransactionDataImporter) ParseImportedData(ctx core.Context, user *models.User, dataTable datatable.TransactionDataTable, defaultTimezoneOffset int16, accountMap map[string]*models.Account, expenseCategoryMap map[string]map[string]*models.TransactionCategory, incomeCategoryMap map[string]map[string]*models.TransactionCategory, transferCategoryMap map[string]map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionTag, error) {
func (c *DataTableTransactionDataImporter) ParseImportedData(ctx core.Context, user *models.User, dataTable datatable.TransactionDataTable, defaultTimezoneOffset int16, additionalOptions TransactionDataImporterOptions, accountMap map[string]*models.Account, expenseCategoryMap map[string]map[string]*models.TransactionCategory, incomeCategoryMap map[string]map[string]*models.TransactionCategory, transferCategoryMap map[string]map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionTag, error) {
if dataTable.TransactionRowCount() < 1 {
log.Errorf(ctx, "[data_table_transaction_data_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, nil, nil, errs.ErrNotFoundTransactionDataInFile
@@ -303,6 +303,7 @@ func (c *DataTableTransactionDataImporter) ParseImportedData(ctx core.Context, u
var tagIds []string
var tagNames []string
tagNamesMap := make(map[string]bool)
if dataTable.HasColumn(datatable.TRANSACTION_DATA_TABLE_TAGS) {
var tagNameItems []string
@@ -316,7 +317,7 @@ func (c *DataTableTransactionDataImporter) ParseImportedData(ctx core.Context, u
for i := 0; i < len(tagNameItems); i++ {
tagName := tagNameItems[i]
if tagName == "" {
if tagName == "" || tagNamesMap[tagName] {
continue
}
@@ -333,6 +334,28 @@ func (c *DataTableTransactionDataImporter) ParseImportedData(ctx core.Context, u
}
tagNames = append(tagNames, tagName)
tagNamesMap[tagName] = true
}
}
if dataTable.HasColumn(datatable.TRANSACTION_DATA_TABLE_PAYEE) && additionalOptions.IsPayeeAsTag() {
payee := dataRow.GetData(datatable.TRANSACTION_DATA_TABLE_PAYEE)
if payee != "" && !tagNamesMap[payee] {
tag, exists := tagMap[payee]
if !exists {
tag = c.createNewTransactionTagModel(user.Uid, payee)
allNewTags = append(allNewTags, tag)
tagMap[payee] = tag
}
if tag != nil {
tagIds = append(tagIds, utils.Int64ToString(tag.TagId))
}
tagNames = append(tagNames, payee)
tagNamesMap[payee] = true
}
}
@@ -342,6 +365,10 @@ func (c *DataTableTransactionDataImporter) ParseImportedData(ctx core.Context, u
description = dataRow.GetData(datatable.TRANSACTION_DATA_TABLE_DESCRIPTION)
}
if description == "" && additionalOptions.IsPayeeAsDescription() && dataTable.HasColumn(datatable.TRANSACTION_DATA_TABLE_PAYEE) {
description = dataRow.GetData(datatable.TRANSACTION_DATA_TABLE_PAYEE)
}
transaction := &models.ImportTransaction{
Transaction: &models.Transaction{
Uid: user.Uid,

View File

@@ -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, expenseCategoryMap map[string]map[string]*models.TransactionCategory, incomeCategoryMap map[string]map[string]*models.TransactionCategory, transferCategoryMap map[string]map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionTag, error)
ParseImportedData(ctx core.Context, user *models.User, data []byte, defaultTimezoneOffset int16, additionalOptions TransactionDataImporterOptions, accountMap map[string]*models.Account, expenseCategoryMap map[string]map[string]*models.TransactionCategory, incomeCategoryMap map[string]map[string]*models.TransactionCategory, transferCategoryMap map[string]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

View File

@@ -0,0 +1,118 @@
package converter
import "strings"
// TransactionDataImporterOptions defines the options for transaction data importer
type TransactionDataImporterOptions struct {
payeeAsTag bool
payeeAsDescription bool
memberAsTag bool
projectAsTag bool
merchantAsTag bool
}
// DefaultImporterOptions provides the default options for transaction data importer
var DefaultImporterOptions = TransactionDataImporterOptions{
payeeAsTag: false,
payeeAsDescription: false,
memberAsTag: false,
projectAsTag: false,
merchantAsTag: false,
}
// IsPayeeAsTag returns whether to import payee as tag
func (o TransactionDataImporterOptions) IsPayeeAsTag() bool {
return o.payeeAsTag
}
// IsPayeeAsDescription returns whether to import payee as description
func (o TransactionDataImporterOptions) IsPayeeAsDescription() bool {
return o.payeeAsDescription
}
// IsMemberAsTag returns whether to import member as tag
func (o TransactionDataImporterOptions) IsMemberAsTag() bool {
return o.memberAsTag
}
// IsProjectAsTag returns whether to import project as tag
func (o TransactionDataImporterOptions) IsProjectAsTag() bool {
return o.projectAsTag
}
// IsMerchantAsTag returns whether to import merchant as tag
func (o TransactionDataImporterOptions) IsMerchantAsTag() bool {
return o.merchantAsTag
}
// WithPayeeAsTag sets the option to import payee as tag
func (o TransactionDataImporterOptions) WithPayeeAsTag() TransactionDataImporterOptions {
cloned := o.Clone()
cloned.payeeAsTag = true
return cloned
}
// WithPayeeAsDescription sets the option to import payee as description
func (o TransactionDataImporterOptions) WithPayeeAsDescription() TransactionDataImporterOptions {
cloned := o.Clone()
cloned.payeeAsDescription = true
return cloned
}
// WithMemberAsTag sets the option to import member as tag
func (o TransactionDataImporterOptions) WithMemberAsTag() TransactionDataImporterOptions {
cloned := o.Clone()
cloned.memberAsTag = true
return cloned
}
// WithProjectAsTag sets the option to import project as tag
func (o TransactionDataImporterOptions) WithProjectAsTag() TransactionDataImporterOptions {
cloned := o.Clone()
cloned.projectAsTag = true
return cloned
}
// WithMerchantAsTag sets the option to import merchant as tag
func (o TransactionDataImporterOptions) WithMerchantAsTag() TransactionDataImporterOptions {
cloned := o.Clone()
cloned.merchantAsTag = true
return cloned
}
// Clone creates a copy of the options instance
func (o TransactionDataImporterOptions) Clone() TransactionDataImporterOptions {
return TransactionDataImporterOptions{
payeeAsTag: o.payeeAsTag,
payeeAsDescription: o.payeeAsDescription,
memberAsTag: o.memberAsTag,
projectAsTag: o.projectAsTag,
merchantAsTag: o.merchantAsTag,
}
}
// ParseImporterOptions parses the textual options to the instance
func ParseImporterOptions(s string) TransactionDataImporterOptions {
options := TransactionDataImporterOptions{}
if s == "" {
return options
}
for _, option := range strings.Split(s, ",") {
switch option {
case "payeeAsTag":
options.payeeAsTag = true
case "payeeAsDescription":
options.payeeAsDescription = true
case "memberAsTag":
options.memberAsTag = true
case "projectAsTag":
options.projectAsTag = true
case "merchantAsTag":
options.merchantAsTag = true
}
}
return options
}

View File

@@ -0,0 +1,110 @@
package converter
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestParseImporterOptions(t *testing.T) {
actualValue := ParseImporterOptions("payeeAsTag,memberAsTag")
expectedValue := TransactionDataImporterOptions{
payeeAsTag: true,
memberAsTag: true,
projectAsTag: false,
merchantAsTag: false,
}
assert.Equal(t, expectedValue, actualValue)
assert.Equal(t, true, actualValue.IsPayeeAsTag())
assert.Equal(t, true, actualValue.IsMemberAsTag())
assert.Equal(t, false, actualValue.IsProjectAsTag())
assert.Equal(t, false, actualValue.IsMerchantAsTag())
actualValue = ParseImporterOptions("")
expectedValue = TransactionDataImporterOptions{
payeeAsTag: false,
memberAsTag: false,
projectAsTag: false,
merchantAsTag: false,
}
assert.Equal(t, expectedValue, actualValue)
assert.Equal(t, false, actualValue.IsPayeeAsTag())
assert.Equal(t, false, actualValue.IsMemberAsTag())
assert.Equal(t, false, actualValue.IsProjectAsTag())
assert.Equal(t, false, actualValue.IsMerchantAsTag())
}
func TestParseImporterOptions_WithAllOptions(t *testing.T) {
actualValue := ParseImporterOptions("payeeAsTag,payeeAsDescription,memberAsTag,projectAsTag,merchantAsTag")
expectedValue := TransactionDataImporterOptions{
payeeAsTag: true,
payeeAsDescription: true,
memberAsTag: true,
projectAsTag: true,
merchantAsTag: true,
}
assert.Equal(t, expectedValue, actualValue)
assert.Equal(t, true, actualValue.IsPayeeAsTag())
assert.Equal(t, true, actualValue.IsPayeeAsDescription())
assert.Equal(t, true, actualValue.IsMemberAsTag())
assert.Equal(t, true, actualValue.IsProjectAsTag())
assert.Equal(t, true, actualValue.IsMerchantAsTag())
}
func TestParseImporterOptions_WithInvalidOptions(t *testing.T) {
actualValue := ParseImporterOptions("invalidOption,payeeAsTag,memberAsTag")
expectedValue := TransactionDataImporterOptions{
payeeAsTag: true,
memberAsTag: true,
projectAsTag: false,
merchantAsTag: false,
}
assert.Equal(t, expectedValue, actualValue)
assert.Equal(t, true, actualValue.IsPayeeAsTag())
assert.Equal(t, true, actualValue.IsMemberAsTag())
assert.Equal(t, false, actualValue.IsProjectAsTag())
assert.Equal(t, false, actualValue.IsMerchantAsTag())
actualValue = ParseImporterOptions("invalidOption")
expectedValue = TransactionDataImporterOptions{
payeeAsTag: false,
memberAsTag: false,
projectAsTag: false,
merchantAsTag: false,
}
assert.Equal(t, expectedValue, actualValue)
assert.Equal(t, false, actualValue.IsPayeeAsTag())
assert.Equal(t, false, actualValue.IsMemberAsTag())
assert.Equal(t, false, actualValue.IsProjectAsTag())
assert.Equal(t, false, actualValue.IsMerchantAsTag())
}
func TestParseImporterOptions_Clone(t *testing.T) {
original := TransactionDataImporterOptions{
payeeAsTag: true,
payeeAsDescription: false,
memberAsTag: false,
projectAsTag: true,
merchantAsTag: false,
}
cloned := original.Clone()
assert.Equal(t, original, cloned)
// Modify cloned options and verify original options are not affected
cloned.payeeAsTag = false
cloned.payeeAsDescription = true
cloned.memberAsTag = true
assert.Equal(t, true, original.payeeAsTag)
assert.Equal(t, false, original.payeeAsDescription)
assert.Equal(t, false, original.memberAsTag)
assert.Equal(t, true, original.projectAsTag)
assert.Equal(t, false, original.merchantAsTag)
assert.Equal(t, false, cloned.payeeAsTag)
assert.Equal(t, true, cloned.payeeAsDescription)
assert.Equal(t, true, cloned.memberAsTag)
assert.Equal(t, true, cloned.projectAsTag)
assert.Equal(t, false, cloned.merchantAsTag)
}

View File

@@ -72,6 +72,10 @@ const (
TRANSACTION_DATA_TABLE_GEOGRAPHIC_LOCATION TransactionDataTableColumn = 12
TRANSACTION_DATA_TABLE_TAGS TransactionDataTableColumn = 13
TRANSACTION_DATA_TABLE_DESCRIPTION TransactionDataTableColumn = 14
TRANSACTION_DATA_TABLE_PAYEE TransactionDataTableColumn = 101
TRANSACTION_DATA_TABLE_MEMBER TransactionDataTableColumn = 102
TRANSACTION_DATA_TABLE_PROJECT TransactionDataTableColumn = 103
TRANSACTION_DATA_TABLE_MERCHANT TransactionDataTableColumn = 104
)
// TRANSACTION_DATA_TABLE_TIMEZONE_NOT_AVAILABLE represents the constant for timezone not available

View File

@@ -35,7 +35,7 @@ var (
)
// ParseImportedData returns the imported data by parsing the transaction json data
func (c *defaultTransactionDataJsonImporter) ParseImportedData(ctx core.Context, user *models.User, data []byte, defaultTimezoneOffset int16, accountMap map[string]*models.Account, expenseCategoryMap map[string]map[string]*models.TransactionCategory, incomeCategoryMap map[string]map[string]*models.TransactionCategory, transferCategoryMap map[string]map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionTag, error) {
func (c *defaultTransactionDataJsonImporter) ParseImportedData(ctx core.Context, user *models.User, data []byte, defaultTimezoneOffset int16, additionalOptions converter.TransactionDataImporterOptions, accountMap map[string]*models.Account, expenseCategoryMap map[string]map[string]*models.TransactionCategory, incomeCategoryMap map[string]map[string]*models.TransactionCategory, transferCategoryMap map[string]map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionTag, error) {
var importRequest models.ImportTransactionRequest
if err := json.Unmarshal(data, &importRequest); err != nil {
@@ -55,7 +55,7 @@ func (c *defaultTransactionDataJsonImporter) ParseImportedData(ctx core.Context,
ezbookkeepingTagSeparator,
)
return dataTableImporter.ParseImportedData(ctx, user, transactionDataTable, defaultTimezoneOffset, accountMap, expenseCategoryMap, incomeCategoryMap, transferCategoryMap, tagMap)
return dataTableImporter.ParseImportedData(ctx, user, transactionDataTable, defaultTimezoneOffset, additionalOptions, accountMap, expenseCategoryMap, incomeCategoryMap, transferCategoryMap, tagMap)
}
func (c *defaultTransactionDataJsonImporter) createNewDefaultTransactionDataTable(importRequest models.ImportTransactionRequest) (datatable.TransactionDataTable, error) {

View File

@@ -84,7 +84,7 @@ func (c *defaultTransactionDataPlainTextConverter) ToExportedContent(ctx core.Co
}
// ParseImportedData returns the imported data by parsing the transaction plain text data
func (c *defaultTransactionDataPlainTextConverter) ParseImportedData(ctx core.Context, user *models.User, data []byte, defaultTimezoneOffset int16, accountMap map[string]*models.Account, expenseCategoryMap map[string]map[string]*models.TransactionCategory, incomeCategoryMap map[string]map[string]*models.TransactionCategory, transferCategoryMap map[string]map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionTag, error) {
func (c *defaultTransactionDataPlainTextConverter) ParseImportedData(ctx core.Context, user *models.User, data []byte, defaultTimezoneOffset int16, additionalOptions converter.TransactionDataImporterOptions, accountMap map[string]*models.Account, expenseCategoryMap map[string]map[string]*models.TransactionCategory, incomeCategoryMap map[string]map[string]*models.TransactionCategory, transferCategoryMap map[string]map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionTag, error) {
dataTable, err := createNewDefaultPlainTextDataTable(
string(data),
c.columnSeparator,
@@ -104,5 +104,5 @@ func (c *defaultTransactionDataPlainTextConverter) ParseImportedData(ctx core.Co
ezbookkeepingTagSeparator,
)
return dataTableImporter.ParseImportedData(ctx, user, transactionDataTable, defaultTimezoneOffset, accountMap, expenseCategoryMap, incomeCategoryMap, transferCategoryMap, tagMap)
return dataTableImporter.ParseImportedData(ctx, user, transactionDataTable, defaultTimezoneOffset, additionalOptions, accountMap, expenseCategoryMap, incomeCategoryMap, transferCategoryMap, tagMap)
}

View File

@@ -5,6 +5,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/mayswind/ezbookkeeping/pkg/converters/converter"
"github.com/mayswind/ezbookkeeping/pkg/core"
"github.com/mayswind/ezbookkeeping/pkg/errs"
"github.com/mayswind/ezbookkeeping/pkg/models"
@@ -12,7 +13,7 @@ import (
)
func TestDefaultTransactionDataCSVFileConverterToExportedContent(t *testing.T) {
converter := DefaultTransactionDataCSVFileConverter
exporter := DefaultTransactionDataCSVFileConverter
context := core.NewNullContext()
transactions := make([]*models.Transaction, 3)
@@ -119,14 +120,14 @@ func TestDefaultTransactionDataCSVFileConverterToExportedContent(t *testing.T) {
"2024-09-01 12:34:56,+08:00,Income,Test Category,Test Sub Category,Test Account,CNY,123.45,,,,123.450000 45.670000,Test Tag;Test Tag2,Hello World\n" +
"2024-09-01 12:34:56,+00:00,Expense,Test Category2,Test Sub Category2,Test Account,CNY,-0.10,,,,,Test Tag,Foo#Bar\n" +
"2024-09-01 12:34:56,-05:00,Transfer,Test Category3,Test Sub Category3,Test Account,CNY,123.45,Test Account2,USD,17.35,,Test Tag2,T\te s t test\n"
actualContent, err := converter.ToExportedContent(context, 123, transactions, accountMap, categoryMap, tagMap, allTagIndexes)
actualContent, err := exporter.ToExportedContent(context, 123, transactions, accountMap, categoryMap, tagMap, allTagIndexes)
assert.Nil(t, err)
assert.Equal(t, expectedContent, string(actualContent))
}
func TestDefaultTransactionDataCSVFileConverterParseImportedData_MinimumValidData(t *testing.T) {
converter := DefaultTransactionDataCSVFileConverter
importer := DefaultTransactionDataCSVFileConverter
context := core.NewNullContext()
user := &models.User{
@@ -134,11 +135,11 @@ func TestDefaultTransactionDataCSVFileConverterParseImportedData_MinimumValidDat
DefaultCurrency: "CNY",
}
allNewTransactions, allNewAccounts, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, allNewTags, err := converter.ParseImportedData(context, user, []byte("Time,Type,Sub Category,Account,Amount,Account2,Account2 Amount\n"+
allNewTransactions, allNewAccounts, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, allNewTags, err := importer.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, nil, nil)
"2024-09-01 23:59:59,Transfer,Test Category3,Test Account,0.05,Test Account2,0.05"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
@@ -197,7 +198,7 @@ func TestDefaultTransactionDataCSVFileConverterParseImportedData_MinimumValidDat
}
func TestDefaultTransactionDataCSVFileConverterParseImportedData_ParseInvalidTime(t *testing.T) {
converter := DefaultTransactionDataCSVFileConverter
importer := DefaultTransactionDataCSVFileConverter
context := core.NewNullContext()
user := &models.User{
@@ -205,17 +206,17 @@ func TestDefaultTransactionDataCSVFileConverterParseImportedData_ParseInvalidTim
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, nil, nil)
_, _, _, _, _, _, err := importer.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, converter.DefaultImporterOptions, 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, nil, nil)
_, _, _, _, _, _, err = importer.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, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrTransactionTimeInvalid.Message)
}
func TestDefaultTransactionDataCSVFileConverterParseImportedData_ParseInvalidType(t *testing.T) {
converter := DefaultTransactionDataCSVFileConverter
importer := DefaultTransactionDataCSVFileConverter
context := core.NewNullContext()
user := &models.User{
@@ -223,13 +224,13 @@ func TestDefaultTransactionDataCSVFileConverterParseImportedData_ParseInvalidTyp
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, nil, nil)
_, _, _, _, _, _, err := importer.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, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrTransactionTypeInvalid.Message)
}
func TestDefaultTransactionDataCSVFileConverterParseImportedData_ParseValidTimezone(t *testing.T) {
converter := DefaultTransactionDataCSVFileConverter
importer := DefaultTransactionDataCSVFileConverter
context := core.NewNullContext()
user := &models.User{
@@ -237,27 +238,27 @@ func TestDefaultTransactionDataCSVFileConverterParseImportedData_ParseValidTimez
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,-10:00,Expense,Test Category,Test Account,123.45,,"), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte("Time,Timezone,Type,Sub Category,Account,Amount,Account2,Account2 Amount\n"+
"2024-09-01 12:34:56,-10:00,Expense,Test Category,Test Account,123.45,,"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
assert.Equal(t, int64(1725230096), utils.GetUnixTimeFromTransactionTime(allNewTransactions[0].TransactionTime))
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte("Time,Timezone,Type,Sub Category,Account,Amount,Account2,Account2 Amount\n"+
"2024-09-01 12:34:56,+00:00,Expense,Test Category,Test Account,123.45,,"), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte("Time,Timezone,Type,Sub Category,Account,Amount,Account2,Account2 Amount\n"+
"2024-09-01 12:34:56,+00:00,Expense,Test Category,Test Account,123.45,,"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
assert.Equal(t, int64(1725194096), utils.GetUnixTimeFromTransactionTime(allNewTransactions[0].TransactionTime))
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte("Time,Timezone,Type,Sub Category,Account,Amount,Account2,Account2 Amount\n"+
"2024-09-01 12:34:56,+12:45,Expense,Test Category,Test Account,123.45,,"), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte("Time,Timezone,Type,Sub Category,Account,Amount,Account2,Account2 Amount\n"+
"2024-09-01 12:34:56,+12:45,Expense,Test Category,Test Account,123.45,,"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
assert.Equal(t, int64(1725148196), utils.GetUnixTimeFromTransactionTime(allNewTransactions[0].TransactionTime))
}
func TestDefaultTransactionDataCSVFileConverterParseImportedData_ParseInvalidTimezone(t *testing.T) {
converter := DefaultTransactionDataCSVFileConverter
importer := DefaultTransactionDataCSVFileConverter
context := core.NewNullContext()
user := &models.User{
@@ -265,13 +266,13 @@ func TestDefaultTransactionDataCSVFileConverterParseImportedData_ParseInvalidTim
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, nil, nil)
_, _, _, _, _, _, err := importer.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, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrTransactionTimeZoneInvalid.Message)
}
func TestDefaultTransactionDataCSVFileConverterParseImportedData_ParseValidAccountCurrency(t *testing.T) {
converter := DefaultTransactionDataCSVFileConverter
importer := DefaultTransactionDataCSVFileConverter
context := core.NewNullContext()
user := &models.User{
@@ -279,9 +280,9 @@ func TestDefaultTransactionDataCSVFileConverterParseImportedData_ParseValidAccou
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 := importer.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, nil, nil)
"2024-09-01 12:34:56,Transfer,Test Category2,Test Account,USD,1.23,Test Account2,EUR,1.10"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
@@ -298,7 +299,7 @@ func TestDefaultTransactionDataCSVFileConverterParseImportedData_ParseValidAccou
}
func TestDefaultTransactionDataCSVFileConverterParseImportedData_ParseInvalidAccountCurrency(t *testing.T) {
converter := DefaultTransactionDataCSVFileConverter
importer := DefaultTransactionDataCSVFileConverter
context := core.NewNullContext()
user := &models.User{
@@ -306,19 +307,19 @@ func TestDefaultTransactionDataCSVFileConverterParseImportedData_ParseInvalidAcc
DefaultCurrency: "CNY",
}
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte("Time,Type,Sub Category,Account,Account Currency,Amount,Account2,Account2 Currency,Account2 Amount\n"+
_, _, _, _, _, _, err := importer.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, nil, nil)
"2024-09-01 12:34:56,Transfer,Test Category3,Test Account,CNY,1.23,Test Account2,EUR,1.10"), 0, converter.DefaultImporterOptions, 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 = importer.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, nil, nil)
"2024-09-01 12:34:56,Transfer,Test Category3,Test Account2,CNY,1.23,Test Account,EUR,1.10"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrAccountCurrencyInvalid.Message)
}
func TestDefaultTransactionDataCSVFileConverterParseImportedData_ParseNotSupportedCurrency(t *testing.T) {
converter := DefaultTransactionDataCSVFileConverter
importer := DefaultTransactionDataCSVFileConverter
context := core.NewNullContext()
user := &models.User{
@@ -326,17 +327,17 @@ func TestDefaultTransactionDataCSVFileConverterParseImportedData_ParseNotSupport
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, nil, nil)
_, _, _, _, _, _, err := importer.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, converter.DefaultImporterOptions, 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, nil, nil)
_, _, _, _, _, _, err = importer.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, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrAccountCurrencyInvalid.Message)
}
func TestDefaultTransactionDataCSVFileConverterParseImportedData_ParseInvalidAmount(t *testing.T) {
converter := DefaultTransactionDataCSVFileConverter
importer := DefaultTransactionDataCSVFileConverter
context := core.NewNullContext()
user := &models.User{
@@ -344,17 +345,17 @@ func TestDefaultTransactionDataCSVFileConverterParseImportedData_ParseInvalidAmo
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, nil, nil)
_, _, _, _, _, _, err := importer.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, converter.DefaultImporterOptions, 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, nil, nil)
_, _, _, _, _, _, err = importer.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, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrAmountInvalid.Message)
}
func TestDefaultTransactionDataCSVFileConverterParseImportedData_ParseNoAmount2(t *testing.T) {
converter := DefaultTransactionDataCSVFileConverter
importer := DefaultTransactionDataCSVFileConverter
context := core.NewNullContext()
user := &models.User{
@@ -362,15 +363,15 @@ func TestDefaultTransactionDataCSVFileConverterParseImportedData_ParseNoAmount2(
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, nil, nil)
allNewTransactions, _, _, _, _, _, err := importer.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, converter.DefaultImporterOptions, 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, nil, nil)
allNewTransactions, _, _, _, _, _, err = importer.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, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, int64(12345), allNewTransactions[0].Amount)
@@ -378,7 +379,7 @@ func TestDefaultTransactionDataCSVFileConverterParseImportedData_ParseNoAmount2(
}
func TestDefaultTransactionDataCSVFileConverterParseImportedData_ParseValidGeographicLocation(t *testing.T) {
converter := DefaultTransactionDataCSVFileConverter
importer := DefaultTransactionDataCSVFileConverter
context := core.NewNullContext()
user := &models.User{
@@ -386,8 +387,8 @@ func TestDefaultTransactionDataCSVFileConverterParseImportedData_ParseValidGeogr
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, nil, nil)
allNewTransactions, _, _, _, _, _, err := importer.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, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
@@ -396,7 +397,7 @@ func TestDefaultTransactionDataCSVFileConverterParseImportedData_ParseValidGeogr
}
func TestDefaultTransactionDataCSVFileConverterParseImportedData_ParseInvalidGeographicLocation(t *testing.T) {
converter := DefaultTransactionDataCSVFileConverter
importer := DefaultTransactionDataCSVFileConverter
context := core.NewNullContext()
user := &models.User{
@@ -404,24 +405,24 @@ func TestDefaultTransactionDataCSVFileConverterParseImportedData_ParseInvalidGeo
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, nil, nil)
allNewTransactions, _, _, _, _, _, err := importer.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, converter.DefaultImporterOptions, 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, nil, nil)
_, _, _, _, _, _, err = importer.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, converter.DefaultImporterOptions, 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, nil, nil)
_, _, _, _, _, _, err = importer.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, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrGeographicLocationInvalid.Message)
}
func TestDefaultTransactionDataCSVFileConverterParseImportedData_ParseTag(t *testing.T) {
converter := DefaultTransactionDataCSVFileConverter
importer := DefaultTransactionDataCSVFileConverter
context := core.NewNullContext()
user := &models.User{
@@ -429,8 +430,8 @@ func TestDefaultTransactionDataCSVFileConverterParseImportedData_ParseTag(t *tes
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, nil, nil)
_, _, _, _, _, allNewTags, err := importer.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, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
@@ -450,7 +451,7 @@ func TestDefaultTransactionDataCSVFileConverterParseImportedData_ParseTag(t *tes
}
func TestDefaultTransactionDataCSVFileConverterParseImportedData_ParseDescription(t *testing.T) {
converter := DefaultTransactionDataCSVFileConverter
importer := DefaultTransactionDataCSVFileConverter
context := core.NewNullContext()
user := &models.User{
@@ -458,8 +459,8 @@ func TestDefaultTransactionDataCSVFileConverterParseImportedData_ParseDescriptio
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, nil, nil)
allNewTransactions, _, _, _, _, _, err := importer.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, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
@@ -467,7 +468,7 @@ func TestDefaultTransactionDataCSVFileConverterParseImportedData_ParseDescriptio
}
func TestDefaultTransactionDataCSVFileConverterParseImportedData_MissingFileHeader(t *testing.T) {
converter := DefaultTransactionDataCSVFileConverter
importer := DefaultTransactionDataCSVFileConverter
context := core.NewNullContext()
user := &models.User{
@@ -475,12 +476,12 @@ func TestDefaultTransactionDataCSVFileConverterParseImportedData_MissingFileHead
DefaultCurrency: "CNY",
}
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(""), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(""), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrNotFoundTransactionDataInFile.Message)
}
func TestDefaultTransactionDataCSVFileConverterParseImportedData_MissingRequiredColumn(t *testing.T) {
converter := DefaultTransactionDataCSVFileConverter
importer := DefaultTransactionDataCSVFileConverter
context := core.NewNullContext()
user := &models.User{
@@ -489,32 +490,32 @@ func TestDefaultTransactionDataCSVFileConverterParseImportedData_MissingRequired
}
// 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, nil, nil)
_, _, _, _, _, _, err := importer.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, converter.DefaultImporterOptions, 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, nil, nil)
_, _, _, _, _, _, err = importer.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, converter.DefaultImporterOptions, 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, nil, nil)
_, _, _, _, _, _, err = importer.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, converter.DefaultImporterOptions, 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, nil, nil)
_, _, _, _, _, _, err = importer.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, converter.DefaultImporterOptions, 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, nil, nil)
_, _, _, _, _, _, err = importer.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, converter.DefaultImporterOptions, 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, nil, nil)
_, _, _, _, _, _, err = importer.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, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrMissingRequiredFieldInHeaderRow.Message)
}

View File

@@ -146,7 +146,7 @@ func (c *customTransactionDataDsvFileImporter) ParseDsvFileLines(ctx core.Contex
}
// ParseImportedData returns the imported data by parsing the custom transaction dsv data
func (c *customTransactionDataDsvFileImporter) ParseImportedData(ctx core.Context, user *models.User, data []byte, defaultTimezoneOffset int16, accountMap map[string]*models.Account, expenseCategoryMap map[string]map[string]*models.TransactionCategory, incomeCategoryMap map[string]map[string]*models.TransactionCategory, transferCategoryMap map[string]map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionTag, error) {
func (c *customTransactionDataDsvFileImporter) ParseImportedData(ctx core.Context, user *models.User, data []byte, defaultTimezoneOffset int16, additionalOptions converter.TransactionDataImporterOptions, accountMap map[string]*models.Account, expenseCategoryMap map[string]map[string]*models.TransactionCategory, incomeCategoryMap map[string]map[string]*models.TransactionCategory, transferCategoryMap map[string]map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionTag, error) {
allLines, err := c.ParseDsvFileLines(ctx, data)
if err != nil {
@@ -157,7 +157,7 @@ func (c *customTransactionDataDsvFileImporter) ParseImportedData(ctx core.Contex
transactionDataTable := CreateNewCustomPlainTextDataTable(dataTable, c.columnIndexMapping, c.transactionTypeNameMapping, c.timeFormat, c.timezoneFormat, c.amountDecimalSeparator, c.amountDigitGroupingSymbol)
dataTableImporter := converter.CreateNewImporterWithTypeNameMapping(customTransactionTypeNameMapping, c.geoLocationSeparator, c.geoLocationOrder, c.transactionTagSeparator)
return dataTableImporter.ParseImportedData(ctx, user, transactionDataTable, defaultTimezoneOffset, accountMap, expenseCategoryMap, incomeCategoryMap, transferCategoryMap, tagMap)
return dataTableImporter.ParseImportedData(ctx, user, transactionDataTable, defaultTimezoneOffset, additionalOptions, accountMap, expenseCategoryMap, incomeCategoryMap, transferCategoryMap, tagMap)
}
// IsDelimiterSeparatedValuesFileType returns whether the file type is the delimiter-separated values file type

View File

@@ -5,6 +5,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/mayswind/ezbookkeeping/pkg/converters/converter"
"github.com/mayswind/ezbookkeeping/pkg/converters/datatable"
"github.com/mayswind/ezbookkeeping/pkg/core"
"github.com/mayswind/ezbookkeeping/pkg/errs"
@@ -22,12 +23,12 @@ func TestIsDelimiterSeparatedValuesFileType(t *testing.T) {
}
func TestCustomTransactionDataDsvFileParser_ParseDsvFileLines(t *testing.T) {
converter, err := CreateNewCustomTransactionDataDsvFileParser("custom_csv", "utf-8")
importer, err := CreateNewCustomTransactionDataDsvFileParser("custom_csv", "utf-8")
assert.Nil(t, err)
context := core.NewNullContext()
allLines, err := converter.ParseDsvFileLines(context, []byte(
allLines, err := importer.ParseDsvFileLines(context, []byte(
"2024-09-01 00:00:00,B,123.45\n"+
"2024-09-01 01:23:45,I,0.12\n"))
assert.Nil(t, err)
@@ -44,10 +45,10 @@ func TestCustomTransactionDataDsvFileParser_ParseDsvFileLines(t *testing.T) {
assert.Equal(t, "I", allLines[1][1])
assert.Equal(t, "0.12", allLines[1][2])
converter, err = CreateNewCustomTransactionDataDsvFileParser("custom_tsv", "utf-8")
importer, err = CreateNewCustomTransactionDataDsvFileParser("custom_tsv", "utf-8")
assert.Nil(t, err)
allLines, err = converter.ParseDsvFileLines(context, []byte(
allLines, err = importer.ParseDsvFileLines(context, []byte(
"2024-09-01 12:34:56\tE\t1.00\n"+
"2024-09-01 23:59:59\tT\t0.05"))
assert.Nil(t, err)
@@ -77,7 +78,7 @@ func TestCustomTransactionDataDsvFileImporter_MinimumValidData(t *testing.T) {
"E": models.TRANSACTION_TYPE_EXPENSE,
"T": models.TRANSACTION_TYPE_TRANSFER,
}
converter, err := CreateNewCustomTransactionDataDsvFileImporter("custom_csv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ss", ".", "", "", "", "", "")
importer, err := CreateNewCustomTransactionDataDsvFileImporter("custom_csv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ss", ".", "", "", "", "", "")
assert.Nil(t, err)
context := core.NewNullContext()
@@ -87,11 +88,11 @@ func TestCustomTransactionDataDsvFileImporter_MinimumValidData(t *testing.T) {
DefaultCurrency: "CNY",
}
allNewTransactions, allNewAccounts, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, allNewTags, err := converter.ParseImportedData(context, user, []byte(
allNewTransactions, allNewAccounts, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, allNewTags, err := importer.ParseImportedData(context, user, []byte(
"2024-09-01 00:00:00,B,123.45\n"+
"2024-09-01 01:23:45,I,0.12\n"+
"2024-09-01 12:34:56,E,1.00\n"+
"2024-09-01 23:59:59,T,0.05"), 0, nil, nil, nil, nil, nil)
"2024-09-01 23:59:59,T,0.05"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
@@ -168,7 +169,7 @@ func TestCustomTransactionDataDsvFileImporter_WithAllSupportedColumns(t *testing
"Expense": models.TRANSACTION_TYPE_EXPENSE,
"Transfer": models.TRANSACTION_TYPE_TRANSFER,
}
converter, err := CreateNewCustomTransactionDataDsvFileImporter("custom_csv", "utf-8", columnIndexMapping, transactionTypeMapping, true, "YYYY-MM-DD HH:mm:ss", "", ".", "", " ", "lonlat", ";")
importer, err := CreateNewCustomTransactionDataDsvFileImporter("custom_csv", "utf-8", columnIndexMapping, transactionTypeMapping, true, "YYYY-MM-DD HH:mm:ss", "", ".", "", " ", "lonlat", ";")
assert.Nil(t, err)
context := core.NewNullContext()
@@ -178,12 +179,12 @@ func TestCustomTransactionDataDsvFileImporter_WithAllSupportedColumns(t *testing
DefaultCurrency: "CNY",
}
allNewTransactions, allNewAccounts, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, allNewTags, err := converter.ParseImportedData(context, user, []byte(
allNewTransactions, allNewAccounts, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, allNewTags, err := importer.ParseImportedData(context, user, []byte(
"\"Time\",\"Timezone\",\"Type\",\"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\",\"Balance Modification\",\"\",\"\",\"Test Account\",\"CNY\",\"123.45\",\"\",\"\",\"\",\"\",\"\",\"\"\n"+
"\"2024-09-01 01:23:45\",\"+08:00\",\"Income\",\"Test Category\",\"Test Sub Category\",\"Test Account\",\"CNY\",\"0.12\",\"\",\"\",\"\",\"123.450000 45.670000\",\"Test Tag;Test Tag2\",\"Hello World\"\n"+
"\"2024-09-01 12:34:56\",\"+00:00\",\"Expense\",\"Test Category2\",\"Test Sub Category2\",\"Test Account\",\"CNY\",\"1.00\",\"\",\"\",\"\",\"\",\"Test Tag\",\"Foo#Bar\"\n"+
"\"2024-09-01 23:59:59\",\"-05:00\",\"Transfer\",\"Test Category3\",\"Test Sub Category3\",\"Test Account\",\"CNY\",\"0.05\",\"Test Account2\",\"USD\",\"0.35\",\"\",\"Test Tag2\",\"foo\tbar\""), 0, nil, nil, nil, nil, nil)
"\"2024-09-01 23:59:59\",\"-05:00\",\"Transfer\",\"Test Category3\",\"Test Sub Category3\",\"Test Account\",\"CNY\",\"0.05\",\"Test Account2\",\"USD\",\"0.35\",\"\",\"Test Tag2\",\"foo\tbar\""), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
@@ -261,7 +262,7 @@ func TestCustomTransactionDataDsvFileImporter_ParseInvalidTime(t *testing.T) {
transactionTypeMapping := map[string]models.TransactionType{
"E": models.TRANSACTION_TYPE_EXPENSE,
}
converter, err := CreateNewCustomTransactionDataDsvFileImporter("custom_csv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ss", "", ".", "", "", "", "")
importer, err := CreateNewCustomTransactionDataDsvFileImporter("custom_csv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ss", "", ".", "", "", "", "")
assert.Nil(t, err)
context := core.NewNullContext()
@@ -271,12 +272,12 @@ func TestCustomTransactionDataDsvFileImporter_ParseInvalidTime(t *testing.T) {
DefaultCurrency: "CNY",
}
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
"2024-09-01T12:34:56,E,123.45"), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"2024-09-01T12:34:56,E,123.45"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrTransactionTimeInvalid.Message)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
"09/01/2024 12:34:56,E,123.45"), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"09/01/2024 12:34:56,E,123.45"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrTransactionTimeInvalid.Message)
}
@@ -292,7 +293,7 @@ func TestCustomTransactionDataDsvFileImporter_ParseTransactionWithoutType(t *tes
"E": models.TRANSACTION_TYPE_EXPENSE,
"T": models.TRANSACTION_TYPE_TRANSFER,
}
converter, err := CreateNewCustomTransactionDataDsvFileImporter("custom_csv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ss", "", ".", "", "", "", "")
importer, err := CreateNewCustomTransactionDataDsvFileImporter("custom_csv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ss", "", ".", "", "", "", "")
assert.Nil(t, err)
context := core.NewNullContext()
@@ -302,8 +303,8 @@ func TestCustomTransactionDataDsvFileImporter_ParseTransactionWithoutType(t *tes
DefaultCurrency: "CNY",
}
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56,A,123.45"), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56,A,123.45"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrNotFoundTransactionDataInFile.Message)
}
@@ -316,7 +317,7 @@ func TestCustomTransactionDataDsvFileImporter_ParseInvalidType(t *testing.T) {
transactionTypeMapping := map[string]models.TransactionType{
"B": 0,
}
converter, err := CreateNewCustomTransactionDataDsvFileImporter("custom_csv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ss", "", ".", "", "", "", "")
importer, err := CreateNewCustomTransactionDataDsvFileImporter("custom_csv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ss", "", ".", "", "", "", "")
assert.Nil(t, err)
context := core.NewNullContext()
@@ -326,8 +327,8 @@ func TestCustomTransactionDataDsvFileImporter_ParseInvalidType(t *testing.T) {
DefaultCurrency: "CNY",
}
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56,B,123.45"), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56,B,123.45"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrTransactionTypeInvalid.Message)
}
@@ -340,7 +341,7 @@ func TestCustomTransactionDataDsvFileImporter_ParseTimeWithTimezone(t *testing.T
transactionTypeMapping := map[string]models.TransactionType{
"E": models.TRANSACTION_TYPE_EXPENSE,
}
converter, err := CreateNewCustomTransactionDataDsvFileImporter("custom_csv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ssZ", "", ".", "", "", "", "")
importer, err := CreateNewCustomTransactionDataDsvFileImporter("custom_csv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ssZ", "", ".", "", "", "", "")
assert.Nil(t, err)
context := core.NewNullContext()
@@ -350,20 +351,20 @@ func TestCustomTransactionDataDsvFileImporter_ParseTimeWithTimezone(t *testing.T
DefaultCurrency: "CNY",
}
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56-10:00,E,123.45"), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56-10:00,E,123.45"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
assert.Equal(t, int64(1725230096), utils.GetUnixTimeFromTransactionTime(allNewTransactions[0].TransactionTime))
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56+00:00,E,123.45"), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56+00:00,E,123.45"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
assert.Equal(t, int64(1725194096), utils.GetUnixTimeFromTransactionTime(allNewTransactions[0].TransactionTime))
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56+12:45,E,123.45"), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56+12:45,E,123.45"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
assert.Equal(t, int64(1725148196), utils.GetUnixTimeFromTransactionTime(allNewTransactions[0].TransactionTime))
@@ -378,7 +379,7 @@ func TestCustomTransactionDataDsvFileImporter_ParseTimeWithTimezone2(t *testing.
transactionTypeMapping := map[string]models.TransactionType{
"E": models.TRANSACTION_TYPE_EXPENSE,
}
converter, err := CreateNewCustomTransactionDataDsvFileImporter("custom_csv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ssZZ", "", ".", "", "", "", "")
importer, err := CreateNewCustomTransactionDataDsvFileImporter("custom_csv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ssZZ", "", ".", "", "", "", "")
assert.Nil(t, err)
context := core.NewNullContext()
@@ -388,20 +389,20 @@ func TestCustomTransactionDataDsvFileImporter_ParseTimeWithTimezone2(t *testing.
DefaultCurrency: "CNY",
}
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56-1000,E,123.45"), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56-1000,E,123.45"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
assert.Equal(t, int64(1725230096), utils.GetUnixTimeFromTransactionTime(allNewTransactions[0].TransactionTime))
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56+0000,E,123.45"), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56+0000,E,123.45"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
assert.Equal(t, int64(1725194096), utils.GetUnixTimeFromTransactionTime(allNewTransactions[0].TransactionTime))
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56+1245,E,123.45"), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56+1245,E,123.45"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
assert.Equal(t, int64(1725148196), utils.GetUnixTimeFromTransactionTime(allNewTransactions[0].TransactionTime))
@@ -417,7 +418,7 @@ func TestCustomTransactionDataDsvFileImporter_ParseValidTimezone(t *testing.T) {
transactionTypeMapping := map[string]models.TransactionType{
"E": models.TRANSACTION_TYPE_EXPENSE,
}
converter, err := CreateNewCustomTransactionDataDsvFileImporter("custom_csv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ss", "", ".", "", "", "", "")
importer, err := CreateNewCustomTransactionDataDsvFileImporter("custom_csv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ss", "", ".", "", "", "", "")
assert.Nil(t, err)
context := core.NewNullContext()
@@ -427,20 +428,20 @@ func TestCustomTransactionDataDsvFileImporter_ParseValidTimezone(t *testing.T) {
DefaultCurrency: "CNY",
}
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56,-10:00,E,123.45"), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56,-10:00,E,123.45"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
assert.Equal(t, int64(1725230096), utils.GetUnixTimeFromTransactionTime(allNewTransactions[0].TransactionTime))
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56,+00:00,E,123.45"), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56,+00:00,E,123.45"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
assert.Equal(t, int64(1725194096), utils.GetUnixTimeFromTransactionTime(allNewTransactions[0].TransactionTime))
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56,+12:45,E,123.45"), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56,+12:45,E,123.45"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
assert.Equal(t, int64(1725148196), utils.GetUnixTimeFromTransactionTime(allNewTransactions[0].TransactionTime))
@@ -456,7 +457,7 @@ func TestCustomTransactionDataDsvFileImporter_ParseValidTimezone2(t *testing.T)
transactionTypeMapping := map[string]models.TransactionType{
"E": models.TRANSACTION_TYPE_EXPENSE,
}
converter, err := CreateNewCustomTransactionDataDsvFileImporter("custom_csv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ss", "ZZ", ".", "", "", "", "")
importer, err := CreateNewCustomTransactionDataDsvFileImporter("custom_csv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ss", "ZZ", ".", "", "", "", "")
assert.Nil(t, err)
context := core.NewNullContext()
@@ -466,20 +467,20 @@ func TestCustomTransactionDataDsvFileImporter_ParseValidTimezone2(t *testing.T)
DefaultCurrency: "CNY",
}
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56,-1000,E,123.45"), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56,-1000,E,123.45"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
assert.Equal(t, int64(1725230096), utils.GetUnixTimeFromTransactionTime(allNewTransactions[0].TransactionTime))
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56,+0000,E,123.45"), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56,+0000,E,123.45"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
assert.Equal(t, int64(1725194096), utils.GetUnixTimeFromTransactionTime(allNewTransactions[0].TransactionTime))
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56,+1245,E,123.45"), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56,+1245,E,123.45"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
assert.Equal(t, int64(1725148196), utils.GetUnixTimeFromTransactionTime(allNewTransactions[0].TransactionTime))
@@ -495,7 +496,7 @@ func TestCustomTransactionDataDsvFileImporter_ParseInvalidTimezoneFormat(t *test
transactionTypeMapping := map[string]models.TransactionType{
"E": models.TRANSACTION_TYPE_EXPENSE,
}
converter, err := CreateNewCustomTransactionDataDsvFileImporter("custom_csv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ss", "z", ".", "", "", "", "")
importer, err := CreateNewCustomTransactionDataDsvFileImporter("custom_csv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ss", "z", ".", "", "", "", "")
assert.Nil(t, err)
context := core.NewNullContext()
@@ -505,8 +506,8 @@ func TestCustomTransactionDataDsvFileImporter_ParseInvalidTimezoneFormat(t *test
DefaultCurrency: "CNY",
}
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56,CST,E,123.45"), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56,CST,E,123.45"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrImportFileTransactionTimezoneFormatInvalid.Message)
}
@@ -520,7 +521,7 @@ func TestCustomTransactionDataDsvFileImporter_ParseInvalidTimezone(t *testing.T)
transactionTypeMapping := map[string]models.TransactionType{
"E": models.TRANSACTION_TYPE_EXPENSE,
}
converter, err := CreateNewCustomTransactionDataDsvFileImporter("custom_csv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ss", "", ".", "", "", "", "")
importer, err := CreateNewCustomTransactionDataDsvFileImporter("custom_csv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ss", "", ".", "", "", "", "")
assert.Nil(t, err)
context := core.NewNullContext()
@@ -530,12 +531,12 @@ func TestCustomTransactionDataDsvFileImporter_ParseInvalidTimezone(t *testing.T)
DefaultCurrency: "CNY",
}
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56,Asia/Shanghai,E,123.45"), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56,Asia/Shanghai,E,123.45"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrTransactionTimeZoneInvalid.Message)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56,-0700,E,123.45"), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56,-0700,E,123.45"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrTransactionTimeZoneInvalid.Message)
}
@@ -549,7 +550,7 @@ func TestCustomTransactionDataDsvFileImporter_ParseInvalidTimezone2(t *testing.T
transactionTypeMapping := map[string]models.TransactionType{
"E": models.TRANSACTION_TYPE_EXPENSE,
}
converter, err := CreateNewCustomTransactionDataDsvFileImporter("custom_csv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ss", "ZZ", ".", "", "", "", "")
importer, err := CreateNewCustomTransactionDataDsvFileImporter("custom_csv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ss", "ZZ", ".", "", "", "", "")
assert.Nil(t, err)
context := core.NewNullContext()
@@ -559,12 +560,12 @@ func TestCustomTransactionDataDsvFileImporter_ParseInvalidTimezone2(t *testing.T
DefaultCurrency: "CNY",
}
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56,Asia/Shanghai,E,123.45"), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56,Asia/Shanghai,E,123.45"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrTransactionTimeZoneInvalid.Message)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56,0700,E,123.45"), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56,0700,E,123.45"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrTransactionTimeZoneInvalid.Message)
}
@@ -577,7 +578,7 @@ func TestCustomTransactionDataDsvFileImporter_ParseAmountWithCustomFormat(t *tes
transactionTypeMapping := map[string]models.TransactionType{
"E": models.TRANSACTION_TYPE_EXPENSE,
}
converter, err := CreateNewCustomTransactionDataDsvFileImporter("custom_tsv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ss", "", ",", ".", "", "", "")
importer, err := CreateNewCustomTransactionDataDsvFileImporter("custom_tsv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ss", "", ",", ".", "", "", "")
assert.Nil(t, err)
context := core.NewNullContext()
@@ -587,8 +588,8 @@ func TestCustomTransactionDataDsvFileImporter_ParseAmountWithCustomFormat(t *tes
DefaultCurrency: "CNY",
}
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56\tE\t1.234,56"), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56\tE\t1.234,56"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
assert.Equal(t, int64(123456), allNewTransactions[0].Amount)
@@ -603,7 +604,7 @@ func TestCustomTransactionDataDsvFileImporter_ParseInvalidAmountWithCustomFormat
transactionTypeMapping := map[string]models.TransactionType{
"E": models.TRANSACTION_TYPE_EXPENSE,
}
converter, err := CreateNewCustomTransactionDataDsvFileImporter("custom_tsv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ss", "", ".", ",", "", "", "")
importer, err := CreateNewCustomTransactionDataDsvFileImporter("custom_tsv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ss", "", ".", ",", "", "", "")
assert.Nil(t, err)
context := core.NewNullContext()
@@ -613,8 +614,8 @@ func TestCustomTransactionDataDsvFileImporter_ParseInvalidAmountWithCustomFormat
DefaultCurrency: "CNY",
}
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56\tE\t1.234,56"), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56\tE\t1.234,56"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrAmountInvalid.Message)
}
@@ -627,7 +628,7 @@ func TestCustomTransactionDataDsvFileImporter_ParseInvalidAmountWithCustomFormat
transactionTypeMapping := map[string]models.TransactionType{
"E": models.TRANSACTION_TYPE_EXPENSE,
}
converter, err := CreateNewCustomTransactionDataDsvFileImporter("custom_tsv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ss", "", ",", "", "", "", "")
importer, err := CreateNewCustomTransactionDataDsvFileImporter("custom_tsv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ss", "", ",", "", "", "", "")
assert.Nil(t, err)
context := core.NewNullContext()
@@ -637,8 +638,8 @@ func TestCustomTransactionDataDsvFileImporter_ParseInvalidAmountWithCustomFormat
DefaultCurrency: "CNY",
}
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56\tE\t1.234,56"), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56\tE\t1.234,56"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrAmountInvalid.Message)
}
@@ -655,7 +656,7 @@ func TestCustomTransactionDataDsvFileImporter_ParsePrimaryCategory(t *testing.T)
"E": models.TRANSACTION_TYPE_EXPENSE,
"T": models.TRANSACTION_TYPE_TRANSFER,
}
converter, err := CreateNewCustomTransactionDataDsvFileImporter("custom_csv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ss", "", ".", "", "", "", "")
importer, err := CreateNewCustomTransactionDataDsvFileImporter("custom_csv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ss", "", ".", "", "", "", "")
assert.Nil(t, err)
context := core.NewNullContext()
@@ -665,11 +666,11 @@ func TestCustomTransactionDataDsvFileImporter_ParsePrimaryCategory(t *testing.T)
DefaultCurrency: "CNY",
}
allNewTransactions, _, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, _, err := converter.ParseImportedData(context, user, []byte(
allNewTransactions, _, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, _, err := importer.ParseImportedData(context, user, []byte(
"2024-09-01 00:00:00,B,,123.45\n"+
"2024-09-01 01:23:45,I,Test Category,0.12\n"+
"2024-09-01 12:34:56,E,Test Category2,1.00\n"+
"2024-09-01 23:59:59,T,Test Category3,0.05"), 0, nil, nil, nil, nil, nil)
"2024-09-01 23:59:59,T,Test Category3,0.05"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
@@ -724,7 +725,7 @@ func TestCustomTransactionDataDsvFileImporter_ParseValidAccountCurrency(t *testi
"B": models.TRANSACTION_TYPE_MODIFY_BALANCE,
"T": models.TRANSACTION_TYPE_TRANSFER,
}
converter, err := CreateNewCustomTransactionDataDsvFileImporter("custom_csv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ss", "", ".", "", "", "", "")
importer, err := CreateNewCustomTransactionDataDsvFileImporter("custom_csv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ss", "", ".", "", "", "", "")
assert.Nil(t, err)
context := core.NewNullContext()
@@ -734,9 +735,9 @@ func TestCustomTransactionDataDsvFileImporter_ParseValidAccountCurrency(t *testi
DefaultCurrency: "CNY",
}
allNewTransactions, allNewAccounts, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
allNewTransactions, allNewAccounts, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"2024-09-01 01:23:45,B,Test Account,USD,123.45,,,\n"+
"2024-09-01 12:34:56,T,Test Account,USD,1.23,Test Account2,EUR,1.10"), 0, nil, nil, nil, nil, nil)
"2024-09-01 12:34:56,T,Test Account,USD,1.23,Test Account2,EUR,1.10"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
@@ -767,7 +768,7 @@ func TestCustomTransactionDataDsvFileImporter_ParseInvalidAccountCurrency(t *tes
"B": models.TRANSACTION_TYPE_MODIFY_BALANCE,
"T": models.TRANSACTION_TYPE_TRANSFER,
}
converter, err := CreateNewCustomTransactionDataDsvFileImporter("custom_csv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ss", "", ".", "", "", "", "")
importer, err := CreateNewCustomTransactionDataDsvFileImporter("custom_csv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ss", "", ".", "", "", "", "")
assert.Nil(t, err)
context := core.NewNullContext()
@@ -777,14 +778,14 @@ func TestCustomTransactionDataDsvFileImporter_ParseInvalidAccountCurrency(t *tes
DefaultCurrency: "CNY",
}
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"2024-09-01 01:23:45,B,Test Account,USD,123.45,,,\n"+
"2024-09-01 12:34:56,T,Test Account,CNY,1.23,Test Account2,EUR,1.10"), 0, nil, nil, nil, nil, nil)
"2024-09-01 12:34:56,T,Test Account,CNY,1.23,Test Account2,EUR,1.10"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrAccountCurrencyInvalid.Message)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"2024-09-01 01:23:45,B,Test Account,USD,123.45,,,\n"+
"2024-09-01 12:34:56,T,Test Account2,CNY,1.23,Test Account,EUR,1.10"), 0, nil, nil, nil, nil, nil)
"2024-09-01 12:34:56,T,Test Account2,CNY,1.23,Test Account,EUR,1.10"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrAccountCurrencyInvalid.Message)
}
@@ -803,7 +804,7 @@ func TestCustomTransactionDataDsvFileImporter_ParseNotSupportedCurrency(t *testi
"B": models.TRANSACTION_TYPE_MODIFY_BALANCE,
"T": models.TRANSACTION_TYPE_TRANSFER,
}
converter, err := CreateNewCustomTransactionDataDsvFileImporter("custom_csv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ss", "", ".", "", "", "", "")
importer, err := CreateNewCustomTransactionDataDsvFileImporter("custom_csv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ss", "", ".", "", "", "", "")
assert.Nil(t, err)
context := core.NewNullContext()
@@ -813,12 +814,12 @@ func TestCustomTransactionDataDsvFileImporter_ParseNotSupportedCurrency(t *testi
DefaultCurrency: "CNY",
}
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
"2024-09-01 01:23:45,B,Test Account,XXX,123.45,,,"), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"2024-09-01 01:23:45,B,Test Account,XXX,123.45,,,"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrAccountCurrencyInvalid.Message)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
"2024-09-01 01:23:45,T,Test Account,USD,123.45,Test Account2,XXX,123.45"), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"2024-09-01 01:23:45,T,Test Account,USD,123.45,Test Account2,XXX,123.45"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrAccountCurrencyInvalid.Message)
}
@@ -835,7 +836,7 @@ func TestCustomTransactionDataDsvFileImporter_ParseValidAmount(t *testing.T) {
"E": models.TRANSACTION_TYPE_EXPENSE,
"T": models.TRANSACTION_TYPE_TRANSFER,
}
converter, err := CreateNewCustomTransactionDataDsvFileImporter("custom_csv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ss", "", ".", "", "", "", "")
importer, err := CreateNewCustomTransactionDataDsvFileImporter("custom_csv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ss", "", ".", "", "", "", "")
assert.Nil(t, err)
context := core.NewNullContext()
@@ -845,11 +846,11 @@ func TestCustomTransactionDataDsvFileImporter_ParseValidAmount(t *testing.T) {
DefaultCurrency: "CNY",
}
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"2024-09-01 00:00:00,B,123.45000000,\n"+
"2024-09-01 01:23:45,I,0.12000000,\n"+
"2024-09-01 12:34:56,E,1.00000000,\n"+
"2024-09-01 23:59:59,T,0.05000000,0.35000000"), 0, nil, nil, nil, nil, nil)
"2024-09-01 23:59:59,T,0.05000000,0.35000000"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
@@ -886,7 +887,7 @@ func TestCustomTransactionDataDsvFileImporter_ParseInvalidAmount(t *testing.T) {
"E": models.TRANSACTION_TYPE_EXPENSE,
"T": models.TRANSACTION_TYPE_TRANSFER,
}
converter, err := CreateNewCustomTransactionDataDsvFileImporter("custom_csv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ss", "", ".", "", "", "", "")
importer, err := CreateNewCustomTransactionDataDsvFileImporter("custom_csv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ss", "", ".", "", "", "", "")
assert.Nil(t, err)
context := core.NewNullContext()
@@ -896,12 +897,12 @@ func TestCustomTransactionDataDsvFileImporter_ParseInvalidAmount(t *testing.T) {
DefaultCurrency: "CNY",
}
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56,E,Test Account,123 45,,"), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56,E,Test Account,123 45,,"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrAmountInvalid.Message)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56,T,Test Account,123.45,Test Account2,123 45"), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56,T,Test Account,123.45,Test Account2,123 45"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrAmountInvalid.Message)
}
@@ -917,7 +918,7 @@ func TestCustomTransactionDataDsvFileImporter_ParseNoAmount2(t *testing.T) {
"E": models.TRANSACTION_TYPE_EXPENSE,
"T": models.TRANSACTION_TYPE_TRANSFER,
}
converter, err := CreateNewCustomTransactionDataDsvFileImporter("custom_csv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ss", "", ".", "", "", "", "")
importer, err := CreateNewCustomTransactionDataDsvFileImporter("custom_csv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ss", "", ".", "", "", "", "")
assert.Nil(t, err)
context := core.NewNullContext()
@@ -927,15 +928,15 @@ func TestCustomTransactionDataDsvFileImporter_ParseNoAmount2(t *testing.T) {
DefaultCurrency: "CNY",
}
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56,E,Test Account,123.45,"), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56,E,Test Account,123.45,"), 0, converter.DefaultImporterOptions, 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(
"2024-09-01 12:34:56,T,Test Account,123.45,Test Account2"), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56,T,Test Account,123.45,Test Account2"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, int64(12345), allNewTransactions[0].Amount)
@@ -952,7 +953,7 @@ func TestCustomTransactionDataDsvFileImporter_ParseValidGeographicLocation(t *te
transactionTypeMapping := map[string]models.TransactionType{
"E": models.TRANSACTION_TYPE_EXPENSE,
}
converter, err := CreateNewCustomTransactionDataDsvFileImporter("custom_csv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ss", "", ".", "", ";", "lonlat", "")
importer, err := CreateNewCustomTransactionDataDsvFileImporter("custom_csv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ss", "", ".", "", ";", "lonlat", "")
assert.Nil(t, err)
context := core.NewNullContext()
@@ -962,8 +963,8 @@ func TestCustomTransactionDataDsvFileImporter_ParseValidGeographicLocation(t *te
DefaultCurrency: "CNY",
}
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56,E,123.45,123.45;45.56"), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56,E,123.45,123.45;45.56"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
@@ -981,7 +982,7 @@ func TestCustomTransactionDataDsvFileImporter_ParseInvalidGeographicLocation(t *
transactionTypeMapping := map[string]models.TransactionType{
"E": models.TRANSACTION_TYPE_EXPENSE,
}
converter, err := CreateNewCustomTransactionDataDsvFileImporter("custom_csv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ss", "", ".", "", " ", "lonlat", "")
importer, err := CreateNewCustomTransactionDataDsvFileImporter("custom_csv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ss", "", ".", "", " ", "lonlat", "")
assert.Nil(t, err)
context := core.NewNullContext()
@@ -991,15 +992,15 @@ func TestCustomTransactionDataDsvFileImporter_ParseInvalidGeographicLocation(t *
DefaultCurrency: "CNY",
}
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56,E,123.45,,,1"), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56,E,123.45,,,1"), 0, converter.DefaultImporterOptions, 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(
"2024-09-01 12:34:56,E,123.45,a b"), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56,E,123.45,a b"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrGeographicLocationInvalid.Message)
}
@@ -1013,7 +1014,7 @@ func TestCustomTransactionDataDsvFileImporter_ParseTag(t *testing.T) {
transactionTypeMapping := map[string]models.TransactionType{
"E": models.TRANSACTION_TYPE_EXPENSE,
}
converter, err := CreateNewCustomTransactionDataDsvFileImporter("custom_csv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ss", "", ".", "", "", "", ";")
importer, err := CreateNewCustomTransactionDataDsvFileImporter("custom_csv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ss", "", ".", "", "", "", ";")
assert.Nil(t, err)
context := core.NewNullContext()
@@ -1023,8 +1024,8 @@ func TestCustomTransactionDataDsvFileImporter_ParseTag(t *testing.T) {
DefaultCurrency: "CNY",
}
_, _, _, _, _, allNewTags, err := converter.ParseImportedData(context, user, []byte(
"2024-09-01 00:00:00,E,123.45,foo;;bar.;#test;hello\tworld;;"), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, allNewTags, err := importer.ParseImportedData(context, user, []byte(
"2024-09-01 00:00:00,E,123.45,foo;;bar.;#test;hello\tworld;;"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
@@ -1053,7 +1054,7 @@ func TestCustomTransactionDataDsvFileImporter_ParseTagWithoutSeparator(t *testin
transactionTypeMapping := map[string]models.TransactionType{
"E": models.TRANSACTION_TYPE_EXPENSE,
}
converter, err := CreateNewCustomTransactionDataDsvFileImporter("custom_csv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ss", "", ".", "", "", "", "")
importer, err := CreateNewCustomTransactionDataDsvFileImporter("custom_csv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ss", "", ".", "", "", "", "")
assert.Nil(t, err)
context := core.NewNullContext()
@@ -1063,8 +1064,8 @@ func TestCustomTransactionDataDsvFileImporter_ParseTagWithoutSeparator(t *testin
DefaultCurrency: "CNY",
}
_, _, _, _, _, allNewTags, err := converter.ParseImportedData(context, user, []byte(
"2024-09-01 00:00:00,E,123.45,foo;;bar.;#test;hello\tworld;;"), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, allNewTags, err := importer.ParseImportedData(context, user, []byte(
"2024-09-01 00:00:00,E,123.45,foo;;bar.;#test;hello\tworld;;"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
@@ -1084,7 +1085,7 @@ func TestCustomTransactionDataDsvFileImporter_ParseDescription(t *testing.T) {
transactionTypeMapping := map[string]models.TransactionType{
"T": models.TRANSACTION_TYPE_TRANSFER,
}
converter, err := CreateNewCustomTransactionDataDsvFileImporter("custom_csv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ss", "", ".", "", "", "", "")
importer, err := CreateNewCustomTransactionDataDsvFileImporter("custom_csv", "utf-8", columnIndexMapping, transactionTypeMapping, false, "YYYY-MM-DD HH:mm:ss", "", ".", "", "", "", "")
assert.Nil(t, err)
context := core.NewNullContext()
@@ -1094,8 +1095,8 @@ func TestCustomTransactionDataDsvFileImporter_ParseDescription(t *testing.T) {
DefaultCurrency: "CNY",
}
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56,T,123.45,foo bar\t#test"), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"2024-09-01 12:34:56,T,123.45,foo bar\t#test"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))

View File

@@ -55,7 +55,7 @@ var (
)
// ParseImportedData returns the imported data by parsing the feidee mymoney app transaction csv data
func (c *feideeMymoneyAppTransactionDataCsvFileImporter) ParseImportedData(ctx core.Context, user *models.User, data []byte, defaultTimezoneOffset int16, accountMap map[string]*models.Account, expenseCategoryMap map[string]map[string]*models.TransactionCategory, incomeCategoryMap map[string]map[string]*models.TransactionCategory, transferCategoryMap map[string]map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionTag, error) {
func (c *feideeMymoneyAppTransactionDataCsvFileImporter) ParseImportedData(ctx core.Context, user *models.User, data []byte, defaultTimezoneOffset int16, additionalOptions converter.TransactionDataImporterOptions, accountMap map[string]*models.Account, expenseCategoryMap map[string]map[string]*models.TransactionCategory, incomeCategoryMap map[string]map[string]*models.TransactionCategory, transferCategoryMap map[string]map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionTag, error) {
fallback := unicode.UTF8.NewDecoder()
reader := transform.NewReader(bytes.NewReader(data), unicode.BOMOverride(fallback))
@@ -91,7 +91,7 @@ func (c *feideeMymoneyAppTransactionDataCsvFileImporter) ParseImportedData(ctx c
dataTableImporter := converter.CreateNewSimpleImporterWithTypeNameMapping(feideeMymoneyTransactionTypeNameMapping)
return dataTableImporter.ParseImportedData(ctx, user, transactionDataTable, defaultTimezoneOffset, accountMap, expenseCategoryMap, incomeCategoryMap, transferCategoryMap, tagMap)
return dataTableImporter.ParseImportedData(ctx, user, transactionDataTable, defaultTimezoneOffset, additionalOptions, accountMap, expenseCategoryMap, incomeCategoryMap, transferCategoryMap, tagMap)
}
func (c *feideeMymoneyAppTransactionDataCsvFileImporter) createNewFeideeMymoneyAppTransactionDataTable(ctx core.Context, commonDataTable datatable.CommonDataTable) (datatable.TransactionDataTable, error) {

View File

@@ -6,6 +6,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/mayswind/ezbookkeeping/pkg/converters/converter"
"github.com/mayswind/ezbookkeeping/pkg/core"
"github.com/mayswind/ezbookkeeping/pkg/errs"
"github.com/mayswind/ezbookkeeping/pkg/models"
@@ -13,7 +14,7 @@ import (
)
func TestFeideeMymoneyCsvFileImporterParseImportedData_MinimumValidData(t *testing.T) {
converter := FeideeMymoneyAppTransactionDataCsvFileImporter
importer := FeideeMymoneyAppTransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -21,7 +22,7 @@ func TestFeideeMymoneyCsvFileImporterParseImportedData_MinimumValidData(t *testi
DefaultCurrency: "CNY",
}
allNewTransactions, allNewAccounts, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, allNewTags, err := converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
allNewTransactions, allNewAccounts, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, allNewTags, err := importer.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,7 +31,7 @@ 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, nil, nil)
"\"转出\",\"2024-09-02 23:59:59\",\"Test Category3\",\"Test Account2\",\"0.5\",\"\",\"00000000-0000-0000-0000-000000000002\""), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
@@ -110,7 +111,7 @@ func TestFeideeMymoneyCsvFileImporterParseImportedData_MinimumValidData(t *testi
}
func TestFeideeMymoneyCsvFileImporterParseImportedData_ParseOutstandingBalanceModification(t *testing.T) {
converter := FeideeMymoneyAppTransactionDataCsvFileImporter
importer := FeideeMymoneyAppTransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -118,10 +119,10 @@ func TestFeideeMymoneyCsvFileImporterParseImportedData_ParseOutstandingBalanceMo
DefaultCurrency: "CNY",
}
allNewTransactions, allNewAccounts, allNewSubExpenseCategories, allNewSubIncomeCategories, _, _, err := converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
allNewTransactions, allNewAccounts, allNewSubExpenseCategories, allNewSubIncomeCategories, _, _, err := importer.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"), 0, nil, nil, nil, nil, nil)
"\"负债变更\",\"2024-09-01 01:00:00\",\"\",\"Test Account2\",\"-0.12\",\"\",\"\"\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
@@ -160,7 +161,7 @@ func TestFeideeMymoneyCsvFileImporterParseImportedData_ParseOutstandingBalanceMo
}
func TestFeideeMymoneyCsvFileImporterParseImportedData_ParseInvalidTime(t *testing.T) {
converter := FeideeMymoneyAppTransactionDataCsvFileImporter
importer := FeideeMymoneyAppTransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -168,19 +169,19 @@ func TestFeideeMymoneyCsvFileImporterParseImportedData_ParseInvalidTime(t *testi
DefaultCurrency: "CNY",
}
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
_, _, _, _, _, _, err := importer.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, nil, nil)
"\"收入\",\"2024-09-01T12:34:56\",\"Test Category\",\"Test Account\",\"0.12\",\"\",\"\""), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrTransactionTimeInvalid.Message)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
_, _, _, _, _, _, err = importer.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, nil, nil)
"\"收入\",\"09/01/2024 12:34:56\",\"Test Category\",\"Test Account\",\"0.12\",\"\",\"\""), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrTransactionTimeInvalid.Message)
}
func TestFeideeMymoneyCsvFileImporterParseImportedData_ParseInvalidType(t *testing.T) {
converter := FeideeMymoneyAppTransactionDataCsvFileImporter
importer := FeideeMymoneyAppTransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -188,14 +189,14 @@ func TestFeideeMymoneyCsvFileImporterParseImportedData_ParseInvalidType(t *testi
DefaultCurrency: "CNY",
}
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
_, _, _, _, _, _, err := importer.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, nil, nil)
"\"Type\",\"2024-09-01 12:34:56\",\"Test Category\",\"Test Account\",\"0.12\",\"\",\"\""), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrTransactionTypeInvalid.Message)
}
func TestFeideeMymoneyCsvFileImporterParseImportedData_ParseValidAccountCurrency(t *testing.T) {
converter := FeideeMymoneyAppTransactionDataCsvFileImporter
importer := FeideeMymoneyAppTransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -203,11 +204,11 @@ func TestFeideeMymoneyCsvFileImporterParseImportedData_ParseValidAccountCurrency
DefaultCurrency: "CNY",
}
allNewTransactions, allNewAccounts, _, _, _, _, err := converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
allNewTransactions, allNewAccounts, _, _, _, _, err := importer.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, nil, nil)
"\"转入\",\"2024-09-01 12:34:56\",\"Test Category3\",\"Test Account2\",\"EUR\",\"1.10\",\"\",\"00000000-0000-0000-0000-000000000001\""), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
@@ -224,7 +225,7 @@ func TestFeideeMymoneyCsvFileImporterParseImportedData_ParseValidAccountCurrency
}
func TestFeideeMymoneyCsvFileImporterParseImportedData_ParseInvalidAccountCurrency(t *testing.T) {
converter := FeideeMymoneyAppTransactionDataCsvFileImporter
importer := FeideeMymoneyAppTransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -232,23 +233,23 @@ func TestFeideeMymoneyCsvFileImporterParseImportedData_ParseInvalidAccountCurren
DefaultCurrency: "CNY",
}
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
_, _, _, _, _, _, err := importer.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, nil, nil)
"\"转入\",\"2024-09-01 12:34:56\",\"Test Category3\",\"Test Account2\",\"EUR\",\"1.10\",\"\",\"00000000-0000-0000-0000-000000000001\""), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrAccountCurrencyInvalid.Message)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
_, _, _, _, _, _, err = importer.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, nil, nil)
"\"转入\",\"2024-09-01 12:34:56\",\"Test Category3\",\"Test Account\",\"EUR\",\"1.10\",\"\",\"00000000-0000-0000-0000-000000000001\""), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrAccountCurrencyInvalid.Message)
}
func TestFeideeMymoneyCsvFileImporterParseImportedData_ParseNotSupportedCurrency(t *testing.T) {
converter := FeideeMymoneyAppTransactionDataCsvFileImporter
importer := FeideeMymoneyAppTransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -256,26 +257,26 @@ func TestFeideeMymoneyCsvFileImporterParseImportedData_ParseNotSupportedCurrency
DefaultCurrency: "CNY",
}
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
_, _, _, _, _, _, err := importer.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, nil, nil)
"\"余额变更\",\"2024-09-01 01:23:45\",\"\",\"Test Account\",\"XXX\",\"123.45\",\"\",\"\""), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrAccountCurrencyInvalid.Message)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
_, _, _, _, _, _, err = importer.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, nil, nil)
"\"转入\",\"2024-09-01 12:34:56\",\"Test Category\",\"Test Account2\",\"XXX\",\"123.45\",\"\",\"00000000-0000-0000-0000-000000000001\""), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrAccountCurrencyInvalid.Message)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
_, _, _, _, _, _, err = importer.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, nil, nil)
"\"转入\",\"2024-09-01 12:34:56\",\"Test Category\",\"Test Account2\",\"USD\",\"123.45\",\"\",\"00000000-0000-0000-0000-000000000001\""), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrAccountCurrencyInvalid.Message)
}
func TestFeideeMymoneyCsvFileImporterParseImportedData_ParseInvalidAmount(t *testing.T) {
converter := FeideeMymoneyAppTransactionDataCsvFileImporter
importer := FeideeMymoneyAppTransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -283,31 +284,31 @@ func TestFeideeMymoneyCsvFileImporterParseImportedData_ParseInvalidAmount(t *tes
DefaultCurrency: "CNY",
}
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
"\"交易类型\",\"日期\",\"子类别\",\"账户\",\"金额\",\"备注\",\"关联Id\"\n"+
"\"余额变更\",\"2024-09-01 01:23:45\",\"\",\"Test Account\",\"123 45\",\"\",\"\""), 0, nil, nil, nil, nil, nil)
"\"余额变更\",\"2024-09-01 01:23:45\",\"\",\"Test Account\",\"123 45\",\"\",\"\""), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrAmountInvalid.Message)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
"\"交易类型\",\"日期\",\"子类别\",\"账户\",\"金额\",\"备注\",\"关联Id\"\n"+
"\"负债变更\",\"2024-09-01 01:23:45\",\"\",\"Test Account\",\"123 45\",\"\",\"\""), 0, nil, nil, nil, nil, nil)
"\"负债变更\",\"2024-09-01 01:23:45\",\"\",\"Test Account\",\"123 45\",\"\",\"\""), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrAmountInvalid.Message)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
_, _, _, _, _, _, err = importer.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, nil, nil)
"\"转入\",\"2024-09-01 12:34:56\",\"Test Category\",\"Test Account2\",\"123.45\",\"\",\"00000000-0000-0000-0000-000000000001\""), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrAmountInvalid.Message)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
_, _, _, _, _, _, err = importer.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, nil, nil)
"\"转入\",\"2024-09-01 12:34:56\",\"Test Category\",\"Test Account2\",\"123 45\",\"\",\"00000000-0000-0000-0000-000000000001\""), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrAmountInvalid.Message)
}
func TestFeideeMymoneyCsvFileImporterParseImportedData_ParseDescription(t *testing.T) {
converter := FeideeMymoneyAppTransactionDataCsvFileImporter
importer := FeideeMymoneyAppTransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -315,10 +316,10 @@ func TestFeideeMymoneyCsvFileImporterParseImportedData_ParseDescription(t *testi
DefaultCurrency: "CNY",
}
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
"\"交易类型\",\"日期\",\"子类别\",\"账户\",\"金额\",\"备注\",\"关联Id\"\n"+
"\"支出\",\"2024-09-01 12:34:56\",\"Test Category\",\"Test Account\",\"123.45\",\"Test\n"+
"A new line break\",\"\""), 0, nil, nil, nil, nil, nil)
"A new line break\",\"\""), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
@@ -326,7 +327,7 @@ func TestFeideeMymoneyCsvFileImporterParseImportedData_ParseDescription(t *testi
}
func TestFeideeMymoneyCsvFileImporterParseImportedData_InvalidRelatedId(t *testing.T) {
converter := FeideeMymoneyAppTransactionDataCsvFileImporter
importer := FeideeMymoneyAppTransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -334,41 +335,41 @@ func TestFeideeMymoneyCsvFileImporterParseImportedData_InvalidRelatedId(t *testi
DefaultCurrency: "CNY",
}
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
_, _, _, _, _, _, err := importer.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, nil, nil)
"\"转出\",\"2024-09-01 23:59:59\",\"Test Category3\",\"Test Account\",\"0.05\",\"\",\"\""), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrRelatedIdCannotBeBlank.Message)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
_, _, _, _, _, _, err = importer.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, nil, nil)
"\"转入\",\"2024-09-01 23:59:59\",\"Test Category3\",\"Test Account\",\"0.05\",\"\",\"\""), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrRelatedIdCannotBeBlank.Message)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
_, _, _, _, _, _, err = importer.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, nil, nil)
"\"转入\",\"2024-09-02 23:59:59\",\"Test Category3\",\"Test Account\",\"0.5\",\"\",\"00000000-0000-0000-0000-000000000002\""), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrFoundRecordNotHasRelatedRecord.Message)
}
func TestFeideeMymoneyCsvFileImporterParseImportedData_MissingFileHeader(t *testing.T) {
converter := FeideeMymoneyAppTransactionDataCsvFileImporter
importer := FeideeMymoneyAppTransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
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, nil, nil)
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte("\"交易类型\",\"日期\",\"子类别\",\"账户\",\"金额\",\"备注\",\"关联Id\"\n"+
"\"余额变更\",\"2024-09-01 00:00:00\",\"\",\"Test Account\",\"123.45\",\"\",\"\"\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrInvalidFileHeader.Message)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(""), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(""), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrInvalidFileHeader.Message)
}
func TestFeideeMymoneyCsvFileImporterParseImportedData_MissingRequiredColumn(t *testing.T) {
converter := FeideeMymoneyAppTransactionDataCsvFileImporter
importer := FeideeMymoneyAppTransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -377,38 +378,38 @@ func TestFeideeMymoneyCsvFileImporterParseImportedData_MissingRequiredColumn(t *
}
// Missing Time Column
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
"\"交易类型\",\"子类别\",\"账户\",\"金额\",\"备注\",\"关联Id\"\n"+
"\"余额变更\",\"\",\"Test Account\",\"123.45\",\"\",\"\"\n"), 0, nil, nil, nil, nil, nil)
"\"余额变更\",\"\",\"Test Account\",\"123.45\",\"\",\"\"\n"), 0, converter.DefaultImporterOptions, 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 = importer.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, nil, nil)
"\"2024-09-01 00:00:00\",\"Test Category\",\"Test Account\",\"123.45\",\"\",\"\"\n"), 0, converter.DefaultImporterOptions, 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 = importer.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, nil, nil)
"\"余额变更\",\"2024-09-01 00:00:00\",\"Test Account\",\"123.45\",\"\",\"\"\n"), 0, converter.DefaultImporterOptions, 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 = importer.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
"\"交易类型\",\"日期\",\"子类别\",\"金额\",\"备注\",\"关联Id\"\n"+
"\"余额变更\",\"2024-09-01 00:00:00\",\"\",\"123.45\",\"\",\"\"\n"), 0, nil, nil, nil, nil, nil)
"\"余额变更\",\"2024-09-01 00:00:00\",\"\",\"123.45\",\"\",\"\"\n"), 0, converter.DefaultImporterOptions, 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 = importer.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
"\"交易类型\",\"日期\",\"子类别\",\"账户\",\"备注\",\"关联Id\"\n"+
"\"余额变更\",\"2024-09-01 00:00:00\",\"\",\"Test Account\",\"\",\"\"\n"), 0, nil, nil, nil, nil, nil)
"\"余额变更\",\"2024-09-01 00:00:00\",\"\",\"Test Account\",\"\",\"\"\n"), 0, converter.DefaultImporterOptions, 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 = importer.ParseImportedData(context, user, []byte("随手记导出文件(headers:v5;xxxxx)\n"+
"\"交易类型\",\"日期\",\"子类别\",\"账户\",\"金额\",\"备注\"\n"+
"\"余额变更\",\"2024-09-01 00:00:00\",\"\",\"Test Account\",\"123.45\",\"\"\n"), 0, nil, nil, nil, nil, nil)
"\"余额变更\",\"2024-09-01 00:00:00\",\"\",\"Test Account\",\"123.45\",\"\"\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrMissingRequiredFieldInHeaderRow.Message)
}

View File

@@ -31,7 +31,7 @@ var (
)
// ParseImportedData returns the imported data by parsing the feidee mymoney (elecloud) transaction xlsx data
func (c *feideeMymoneyElecloudTransactionDataXlsxFileImporter) ParseImportedData(ctx core.Context, user *models.User, data []byte, defaultTimezoneOffset int16, accountMap map[string]*models.Account, expenseCategoryMap map[string]map[string]*models.TransactionCategory, incomeCategoryMap map[string]map[string]*models.TransactionCategory, transferCategoryMap map[string]map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionTag, error) {
func (c *feideeMymoneyElecloudTransactionDataXlsxFileImporter) ParseImportedData(ctx core.Context, user *models.User, data []byte, defaultTimezoneOffset int16, additionalOptions converter.TransactionDataImporterOptions, accountMap map[string]*models.Account, expenseCategoryMap map[string]map[string]*models.TransactionCategory, incomeCategoryMap map[string]map[string]*models.TransactionCategory, transferCategoryMap map[string]map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionTag, error) {
dataTable, err := excel.CreateNewExcelOOXMLFileBasicDataTable(data, true)
if err != nil {
@@ -42,5 +42,5 @@ func (c *feideeMymoneyElecloudTransactionDataXlsxFileImporter) ParseImportedData
transactionDataTable := datatable.CreateNewTransactionDataTableFromBasicDataTableWithRowParser(dataTable, feideeMymoneyElecloudDataColumnNameMapping, transactionRowParser)
dataTableImporter := converter.CreateNewSimpleImporter(feideeMymoneyElecloudTransactionTypeNameMapping)
return dataTableImporter.ParseImportedData(ctx, user, transactionDataTable, defaultTimezoneOffset, accountMap, expenseCategoryMap, incomeCategoryMap, transferCategoryMap, tagMap)
return dataTableImporter.ParseImportedData(ctx, user, transactionDataTable, defaultTimezoneOffset, additionalOptions, accountMap, expenseCategoryMap, incomeCategoryMap, transferCategoryMap, tagMap)
}

View File

@@ -7,13 +7,14 @@ import (
"github.com/stretchr/testify/assert"
"github.com/mayswind/ezbookkeeping/pkg/converters/converter"
"github.com/mayswind/ezbookkeeping/pkg/core"
"github.com/mayswind/ezbookkeeping/pkg/models"
"github.com/mayswind/ezbookkeeping/pkg/utils"
)
func TestFeideeMymoneyElecloudTransactionDataXlsxImporterParseImportedData_MinimumValidData(t *testing.T) {
converter := FeideeMymoneyElecloudTransactionDataXlsxFileImporter
importer := FeideeMymoneyElecloudTransactionDataXlsxFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -24,7 +25,7 @@ func TestFeideeMymoneyElecloudTransactionDataXlsxImporterParseImportedData_Minim
testdata, err := os.ReadFile("../../../testdata/feidee_mymoney_elecloud_test_file.xlsx")
assert.Nil(t, err)
allNewTransactions, allNewAccounts, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, allNewTags, err := converter.ParseImportedData(context, user, testdata, 0, nil, nil, nil, nil, nil)
allNewTransactions, allNewAccounts, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, allNewTags, err := importer.ParseImportedData(context, user, testdata, 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 7, len(allNewTransactions))

View File

@@ -30,7 +30,7 @@ var (
)
// ParseImportedData returns the imported data by parsing the feidee mymoney (web) transaction xls data
func (c *feideeMymoneyWebTransactionDataXlsFileImporter) ParseImportedData(ctx core.Context, user *models.User, data []byte, defaultTimezoneOffset int16, accountMap map[string]*models.Account, expenseCategoryMap map[string]map[string]*models.TransactionCategory, incomeCategoryMap map[string]map[string]*models.TransactionCategory, transferCategoryMap map[string]map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionTag, error) {
func (c *feideeMymoneyWebTransactionDataXlsFileImporter) ParseImportedData(ctx core.Context, user *models.User, data []byte, defaultTimezoneOffset int16, additionalOptions converter.TransactionDataImporterOptions, accountMap map[string]*models.Account, expenseCategoryMap map[string]map[string]*models.TransactionCategory, incomeCategoryMap map[string]map[string]*models.TransactionCategory, transferCategoryMap map[string]map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionTag, error) {
dataTable, err := excel.CreateNewExcelMSCFBFileBasicDataTable(data, true)
if err != nil {
@@ -41,5 +41,5 @@ func (c *feideeMymoneyWebTransactionDataXlsFileImporter) ParseImportedData(ctx c
transactionDataTable := datatable.CreateNewTransactionDataTableFromBasicDataTableWithRowParser(dataTable, feideeMymoneyWebDataColumnNameMapping, transactionRowParser)
dataTableImporter := converter.CreateNewSimpleImporterWithTypeNameMapping(feideeMymoneyTransactionTypeNameMapping)
return dataTableImporter.ParseImportedData(ctx, user, transactionDataTable, defaultTimezoneOffset, accountMap, expenseCategoryMap, incomeCategoryMap, transferCategoryMap, tagMap)
return dataTableImporter.ParseImportedData(ctx, user, transactionDataTable, defaultTimezoneOffset, additionalOptions, accountMap, expenseCategoryMap, incomeCategoryMap, transferCategoryMap, tagMap)
}

View File

@@ -7,13 +7,14 @@ import (
"github.com/stretchr/testify/assert"
"github.com/mayswind/ezbookkeeping/pkg/converters/converter"
"github.com/mayswind/ezbookkeeping/pkg/core"
"github.com/mayswind/ezbookkeeping/pkg/models"
"github.com/mayswind/ezbookkeeping/pkg/utils"
)
func TestFeideeMymoneyTransactionDataXlsImporterParseImportedData_MinimumValidData(t *testing.T) {
converter := FeideeMymoneyWebTransactionDataXlsFileImporter
importer := FeideeMymoneyWebTransactionDataXlsFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -24,7 +25,7 @@ func TestFeideeMymoneyTransactionDataXlsImporterParseImportedData_MinimumValidDa
testdata, err := os.ReadFile("../../../testdata/feidee_mymoney_test_file.xls")
assert.Nil(t, err)
allNewTransactions, allNewAccounts, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, allNewTags, err := converter.ParseImportedData(context, user, testdata, 0, nil, nil, nil, nil, nil)
allNewTransactions, allNewAccounts, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, allNewTags, err := importer.ParseImportedData(context, user, testdata, 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 7, len(allNewTransactions))

View File

@@ -40,7 +40,7 @@ var (
)
// ParseImportedData returns the imported data by parsing the firefly III transaction csv data
func (c *fireflyIIITransactionDataCsvFileImporter) ParseImportedData(ctx core.Context, user *models.User, data []byte, defaultTimezoneOffset int16, accountMap map[string]*models.Account, expenseCategoryMap map[string]map[string]*models.TransactionCategory, incomeCategoryMap map[string]map[string]*models.TransactionCategory, transferCategoryMap map[string]map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionTag, error) {
func (c *fireflyIIITransactionDataCsvFileImporter) ParseImportedData(ctx core.Context, user *models.User, data []byte, defaultTimezoneOffset int16, additionalOptions converter.TransactionDataImporterOptions, accountMap map[string]*models.Account, expenseCategoryMap map[string]map[string]*models.TransactionCategory, incomeCategoryMap map[string]map[string]*models.TransactionCategory, transferCategoryMap map[string]map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionTag, error) {
reader := bytes.NewReader(data)
dataTable, err := csv.CreateNewCsvBasicDataTable(ctx, reader, true)
@@ -52,5 +52,5 @@ func (c *fireflyIIITransactionDataCsvFileImporter) ParseImportedData(ctx core.Co
transactionDataTable := datatable.CreateNewTransactionDataTableFromBasicDataTableWithRowParser(dataTable, fireflyIIITransactionDataColumnNameMapping, transactionRowParser)
dataTableImporter := converter.CreateNewImporterWithTypeNameMapping(fireflyIIITransactionTypeNameMapping, "", "", ",")
return dataTableImporter.ParseImportedData(ctx, user, transactionDataTable, defaultTimezoneOffset, accountMap, expenseCategoryMap, incomeCategoryMap, transferCategoryMap, tagMap)
return dataTableImporter.ParseImportedData(ctx, user, transactionDataTable, defaultTimezoneOffset, additionalOptions, accountMap, expenseCategoryMap, incomeCategoryMap, transferCategoryMap, tagMap)
}

View File

@@ -5,14 +5,15 @@ import (
"github.com/stretchr/testify/assert"
"github.com/mayswind/ezbookkeeping/pkg/converters/converter"
"github.com/mayswind/ezbookkeeping/pkg/core"
"github.com/mayswind/ezbookkeeping/pkg/errs"
"github.com/mayswind/ezbookkeeping/pkg/models"
"github.com/mayswind/ezbookkeeping/pkg/utils"
)
func TestFireFlyIIICsvFileConverterParseImportedData_MinimumValidData(t *testing.T) {
converter := FireflyIIITransactionDataCsvFileImporter
func TestFireFlyIIICsvFileimporterParseImportedData_MinimumValidData(t *testing.T) {
importer := FireflyIIITransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -20,11 +21,11 @@ func TestFireFlyIIICsvFileConverterParseImportedData_MinimumValidData(t *testing
DefaultCurrency: "CNY",
}
allNewTransactions, allNewAccounts, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, allNewTags, err := converter.ParseImportedData(context, user, []byte("type,amount,date,source_name,destination_name,category\n"+
allNewTransactions, allNewAccounts, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, allNewTags, err := importer.ParseImportedData(context, user, []byte("type,amount,date,source_name,destination_name,category\n"+
"\"Opening balance\",123.45,2024-09-01T00:00:00+08:00,\"Initial balance for \"\"Test Account\"\"\",\"Test Account\",\n"+
"Deposit,0.12,2024-09-01T01:23:45+08:00,\"A revenue account\",\"Test Account\",\"Test Category\"\n"+
"Withdrawal,-1.00,2024-09-01T12:34:56+08:00,\"Test Account\",\"A expense account\",\"Test Category2\"\n"+
"Transfer,0.05,2024-09-01T23:59:59+08:00,\"Test Account\",\"Test Account2\",\"Test Category3\""), 0, nil, nil, nil, nil, nil)
"Transfer,0.05,2024-09-01T23:59:59+08:00,\"Test Account\",\"Test Account2\",\"Test Category3\""), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
@@ -82,8 +83,8 @@ func TestFireFlyIIICsvFileConverterParseImportedData_MinimumValidData(t *testing
assert.Equal(t, "Test Category3", allNewSubTransferCategories[0].Name)
}
func TestFireFlyIIICsvFileConverterParseImportedData_ParseInvalidTime(t *testing.T) {
converter := FireflyIIITransactionDataCsvFileImporter
func TestFireFlyIIICsvFileimporterParseImportedData_ParseInvalidTime(t *testing.T) {
importer := FireflyIIITransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -91,17 +92,17 @@ func TestFireFlyIIICsvFileConverterParseImportedData_ParseInvalidTime(t *testing
DefaultCurrency: "CNY",
}
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte("type,amount,date,source_name,destination_name,category\n"+
"Withdrawal,-1.00,2024-09-01T12:34:56,\"Test Account\",\"A expense account\",\"Test Category\""), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte("type,amount,date,source_name,destination_name,category\n"+
"Withdrawal,-1.00,2024-09-01T12:34:56,\"Test Account\",\"A expense account\",\"Test Category\""), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrTransactionTimeInvalid.Message)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte("type,amount,date,source_name,destination_name,category\n"+
"Withdrawal,-1.00,2024-09-01 12:34:56+08:00,\"Test Account\",\"A expense account\",\"Test Category\""), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte("type,amount,date,source_name,destination_name,category\n"+
"Withdrawal,-1.00,2024-09-01 12:34:56+08:00,\"Test Account\",\"A expense account\",\"Test Category\""), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrTransactionTimeInvalid.Message)
}
func TestFireFlyIIICsvFileConverterParseImportedData_ParseInvalidType(t *testing.T) {
converter := FireflyIIITransactionDataCsvFileImporter
func TestFireFlyIIICsvFileimporterParseImportedData_ParseInvalidType(t *testing.T) {
importer := FireflyIIITransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -109,13 +110,13 @@ func TestFireFlyIIICsvFileConverterParseImportedData_ParseInvalidType(t *testing
DefaultCurrency: "CNY",
}
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte("type,amount,date,source_name,destination_name,category\n"+
"Type,123.45,2024-09-01T12:34:56+08:00,\"Test Account\",\"A expense account\",\"Test Category\""), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte("type,amount,date,source_name,destination_name,category\n"+
"Type,123.45,2024-09-01T12:34:56+08:00,\"Test Account\",\"A expense account\",\"Test Category\""), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrTransactionTypeInvalid.Message)
}
func TestFireFlyIIICsvFileConverterParseImportedData_ParseAccountNameAsCategoryName(t *testing.T) {
converter := FireflyIIITransactionDataCsvFileImporter
func TestFireFlyIIICsvFileimporterParseImportedData_ParseAccountNameAsCategoryName(t *testing.T) {
importer := FireflyIIITransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -123,23 +124,23 @@ func TestFireFlyIIICsvFileConverterParseImportedData_ParseAccountNameAsCategoryN
DefaultCurrency: "CNY",
}
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte("type,amount,date,source_name,destination_name,category\n"+
"Withdrawal,-1.00,2024-09-01T12:34:56+08:00,\"Test Account\",\"A expense account\",\"\""), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte("type,amount,date,source_name,destination_name,category\n"+
"Withdrawal,-1.00,2024-09-01T12:34:56+08:00,\"Test Account\",\"A expense account\",\"\""), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
assert.Equal(t, "A expense account", allNewTransactions[0].OriginalCategoryName)
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte("type,amount,date,source_name,destination_name,category\n"+
"Deposit,10.00,2024-09-01T12:34:56+08:00,\"A revenue account\",\"Test Account\",\"\""), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte("type,amount,date,source_name,destination_name,category\n"+
"Deposit,10.00,2024-09-01T12:34:56+08:00,\"A revenue account\",\"Test Account\",\"\""), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
assert.Equal(t, "A revenue account", allNewTransactions[0].OriginalCategoryName)
}
func TestFireFlyIIICsvFileConverterParseImportedData_ParseValidTimezone(t *testing.T) {
converter := FireflyIIITransactionDataCsvFileImporter
func TestFireFlyIIICsvFileimporterParseImportedData_ParseValidTimezone(t *testing.T) {
importer := FireflyIIITransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -147,27 +148,27 @@ func TestFireFlyIIICsvFileConverterParseImportedData_ParseValidTimezone(t *testi
DefaultCurrency: "CNY",
}
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte("type,amount,date,source_name,destination_name,category\n"+
"Withdrawal,-1.00,2024-09-01T12:34:56-10:00,\"Test Account\",\"A expense account\",\"Test Category\""), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte("type,amount,date,source_name,destination_name,category\n"+
"Withdrawal,-1.00,2024-09-01T12:34:56-10:00,\"Test Account\",\"A expense account\",\"Test Category\""), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
assert.Equal(t, int64(1725230096), utils.GetUnixTimeFromTransactionTime(allNewTransactions[0].TransactionTime))
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte("type,amount,date,source_name,destination_name,category\n"+
"Withdrawal,-1.00,2024-09-01T12:34:56+00:00,\"Test Account\",\"A expense account\",\"Test Category\""), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte("type,amount,date,source_name,destination_name,category\n"+
"Withdrawal,-1.00,2024-09-01T12:34:56+00:00,\"Test Account\",\"A expense account\",\"Test Category\""), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
assert.Equal(t, int64(1725194096), utils.GetUnixTimeFromTransactionTime(allNewTransactions[0].TransactionTime))
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte("type,amount,date,source_name,destination_name,category\n"+
"Withdrawal,-1.00,2024-09-01T12:34:56+12:45,\"Test Account\",\"A expense account\",\"Test Category\""), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte("type,amount,date,source_name,destination_name,category\n"+
"Withdrawal,-1.00,2024-09-01T12:34:56+12:45,\"Test Account\",\"A expense account\",\"Test Category\""), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
assert.Equal(t, int64(1725148196), utils.GetUnixTimeFromTransactionTime(allNewTransactions[0].TransactionTime))
}
func TestFireFlyIIICsvFileConverterParseImportedData_ParseValidAccountCurrency(t *testing.T) {
converter := FireflyIIITransactionDataCsvFileImporter
func TestFireFlyIIICsvFileimporterParseImportedData_ParseValidAccountCurrency(t *testing.T) {
importer := FireflyIIITransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -175,9 +176,9 @@ func TestFireFlyIIICsvFileConverterParseImportedData_ParseValidAccountCurrency(t
DefaultCurrency: "CNY",
}
allNewTransactions, allNewAccounts, _, _, _, _, err := converter.ParseImportedData(context, user, []byte("type,amount,foreign_amount,date,currency_code,foreign_currency_code,source_name,destination_name,category\n"+
allNewTransactions, allNewAccounts, _, _, _, _, err := importer.ParseImportedData(context, user, []byte("type,amount,foreign_amount,date,currency_code,foreign_currency_code,source_name,destination_name,category\n"+
"\"Opening balance\",123.45,,2024-09-01T00:00:00+08:00,USD,,\"Initial balance for \"\"Test Account\"\"\",\"Test Account\",\n"+
"Transfer,1.23,1.10,2024-09-01T23:59:59+08:00,USD,EUR,\"Test Account\",\"Test Account2\",\"Test Category2\""), 0, nil, nil, nil, nil, nil)
"Transfer,1.23,1.10,2024-09-01T23:59:59+08:00,USD,EUR,\"Test Account\",\"Test Account2\",\"Test Category2\""), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
@@ -193,8 +194,8 @@ func TestFireFlyIIICsvFileConverterParseImportedData_ParseValidAccountCurrency(t
assert.Equal(t, "EUR", allNewAccounts[1].Currency)
}
func TestFireFlyIIICsvFileConverterParseImportedData_ParseValidForeignAmountAndCurrency(t *testing.T) {
converter := FireflyIIITransactionDataCsvFileImporter
func TestFireFlyIIICsvFileimporterParseImportedData_ParseValidForeignAmountAndCurrency(t *testing.T) {
importer := FireflyIIITransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -202,8 +203,8 @@ func TestFireFlyIIICsvFileConverterParseImportedData_ParseValidForeignAmountAndC
DefaultCurrency: "CNY",
}
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte("type,amount,foreign_amount,date,currency_code,foreign_currency_code,source_name,destination_name,category\n"+
"Transfer,10.00,15.00,2024-09-01T12:34:56+08:00,USD,EUR,\"Test Account\",\"Test Account2\",\"Test Category\""), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte("type,amount,foreign_amount,date,currency_code,foreign_currency_code,source_name,destination_name,category\n"+
"Transfer,10.00,15.00,2024-09-01T12:34:56+08:00,USD,EUR,\"Test Account\",\"Test Account2\",\"Test Category\""), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
@@ -213,8 +214,8 @@ func TestFireFlyIIICsvFileConverterParseImportedData_ParseValidForeignAmountAndC
assert.Equal(t, "USD", allNewTransactions[0].OriginalSourceAccountCurrency)
assert.Equal(t, "EUR", allNewTransactions[0].OriginalDestinationAccountCurrency)
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte("type,amount,date,currency_code,foreign_currency_code,source_name,destination_name,category\n"+
"Transfer,10.00,2024-09-01T12:34:56+08:00,USD,EUR,\"Test Account\",\"Test Account2\",\"Test Category\""), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte("type,amount,date,currency_code,foreign_currency_code,source_name,destination_name,category\n"+
"Transfer,10.00,2024-09-01T12:34:56+08:00,USD,EUR,\"Test Account\",\"Test Account2\",\"Test Category\""), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
@@ -223,8 +224,8 @@ func TestFireFlyIIICsvFileConverterParseImportedData_ParseValidForeignAmountAndC
assert.Equal(t, "USD", allNewTransactions[0].OriginalSourceAccountCurrency)
assert.Equal(t, "EUR", allNewTransactions[0].OriginalDestinationAccountCurrency)
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte("type,amount,date,currency_code,foreign_currency_code,source_name,destination_name,category\n"+
"Transfer,10.00,2024-09-01T12:34:56+08:00,USD,,\"Test Account\",\"Test Account2\",\"Test Category\""), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte("type,amount,date,currency_code,foreign_currency_code,source_name,destination_name,category\n"+
"Transfer,10.00,2024-09-01T12:34:56+08:00,USD,,\"Test Account\",\"Test Account2\",\"Test Category\""), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
@@ -232,8 +233,8 @@ func TestFireFlyIIICsvFileConverterParseImportedData_ParseValidForeignAmountAndC
assert.Equal(t, "USD", allNewTransactions[0].OriginalDestinationAccountCurrency)
}
func TestFireFlyIIICsvFileConverterParseImportedData_ParseInvalidAccountCurrency(t *testing.T) {
converter := FireflyIIITransactionDataCsvFileImporter
func TestFireFlyIIICsvFileimporterParseImportedData_ParseInvalidAccountCurrency(t *testing.T) {
importer := FireflyIIITransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -241,19 +242,19 @@ func TestFireFlyIIICsvFileConverterParseImportedData_ParseInvalidAccountCurrency
DefaultCurrency: "CNY",
}
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte("type,amount,foreign_amount,date,currency_code,foreign_currency_code,source_name,destination_name,category\n"+
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte("type,amount,foreign_amount,date,currency_code,foreign_currency_code,source_name,destination_name,category\n"+
"\"Opening balance\",123.45,,2024-09-01T00:00:00+08:00,USD,,\"Initial balance for \"\"Test Account\"\"\",\"Test Account\",\n"+
"Transfer,1.23,1.10,2024-09-01T23:59:59+08:00,CNY,EUR,\"Test Account\",\"Test Account2\",\"Test Category3\""), 0, nil, nil, nil, nil, nil)
"Transfer,1.23,1.10,2024-09-01T23:59:59+08:00,CNY,EUR,\"Test Account\",\"Test Account2\",\"Test Category3\""), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrAccountCurrencyInvalid.Message)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte("type,amount,foreign_amount,date,currency_code,foreign_currency_code,source_name,destination_name,category\n"+
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte("type,amount,foreign_amount,date,currency_code,foreign_currency_code,source_name,destination_name,category\n"+
"\"Opening balance\",123.45,,2024-09-01T00:00:00+08:00,USD,,\"Initial balance for \"\"Test Account\"\"\",\"Test Account\",\n"+
"Transfer,1.23,1.10,2024-09-01T23:59:59+08:00,CNY,EUR,\"Test Account2\",\"Test Account\",\"Test Category3\""), 0, nil, nil, nil, nil, nil)
"Transfer,1.23,1.10,2024-09-01T23:59:59+08:00,CNY,EUR,\"Test Account2\",\"Test Account\",\"Test Category3\""), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrAccountCurrencyInvalid.Message)
}
func TestFireFlyIIICsvFileConverterParseImportedData_ParseNotSupportedCurrency(t *testing.T) {
converter := FireflyIIITransactionDataCsvFileImporter
func TestFireFlyIIICsvFileimporterParseImportedData_ParseNotSupportedCurrency(t *testing.T) {
importer := FireflyIIITransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -261,17 +262,17 @@ func TestFireFlyIIICsvFileConverterParseImportedData_ParseNotSupportedCurrency(t
DefaultCurrency: "CNY",
}
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte("type,amount,foreign_amount,date,currency_code,foreign_currency_code,source_name,destination_name,category\n"+
"\"Opening balance\",123.45,,2024-09-01T00:00:00+08:00,XXX,,\"Initial balance for \"\"Test Account\"\"\",\"Test Account\",\n"), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte("type,amount,foreign_amount,date,currency_code,foreign_currency_code,source_name,destination_name,category\n"+
"\"Opening balance\",123.45,,2024-09-01T00:00:00+08:00,XXX,,\"Initial balance for \"\"Test Account\"\"\",\"Test Account\",\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrAccountCurrencyInvalid.Message)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte("type,amount,foreign_amount,date,currency_code,foreign_currency_code,source_name,destination_name,category\n"+
"Transfer,123.45,123.45,2024-09-01T23:59:59+08:00,USD,XXX,\"Test Account\",\"Test Account2\",\"Test Category2\""), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte("type,amount,foreign_amount,date,currency_code,foreign_currency_code,source_name,destination_name,category\n"+
"Transfer,123.45,123.45,2024-09-01T23:59:59+08:00,USD,XXX,\"Test Account\",\"Test Account2\",\"Test Category2\""), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrAccountCurrencyInvalid.Message)
}
func TestFireFlyIIICsvFileConverterParseImportedData_ParseInvalidAmount(t *testing.T) {
converter := FireflyIIITransactionDataCsvFileImporter
func TestFireFlyIIICsvFileimporterParseImportedData_ParseInvalidAmount(t *testing.T) {
importer := FireflyIIITransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -279,17 +280,17 @@ func TestFireFlyIIICsvFileConverterParseImportedData_ParseInvalidAmount(t *testi
DefaultCurrency: "CNY",
}
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte("type,amount,date,source_name,destination_name,category\n"+
"Withdrawal,-123 45,2024-09-01T12:34:56+08:00,\"Test Account\",\"A expense account\",\"Test Category\"\n"), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte("type,amount,date,source_name,destination_name,category\n"+
"Withdrawal,-123 45,2024-09-01T12:34:56+08:00,\"Test Account\",\"A expense account\",\"Test Category\"\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrAmountInvalid.Message)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte("type,amount,foreign_amount,date,source_name,destination_name,category\n"+
"Transfer,123.45,123 45,2024-09-01T23:59:59+08:00,\"Test Account\",\"Test Account2\",\"Test Category2\""), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte("type,amount,foreign_amount,date,source_name,destination_name,category\n"+
"Transfer,123.45,123 45,2024-09-01T23:59:59+08:00,\"Test Account\",\"Test Account2\",\"Test Category2\""), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrAmountInvalid.Message)
}
func TestFireFlyIIICsvFileConverterParseImportedData_ParseDescription(t *testing.T) {
converter := FireflyIIITransactionDataCsvFileImporter
func TestFireFlyIIICsvFileimporterParseImportedData_ParseDescription(t *testing.T) {
importer := FireflyIIITransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -297,16 +298,16 @@ func TestFireFlyIIICsvFileConverterParseImportedData_ParseDescription(t *testing
DefaultCurrency: "CNY",
}
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte("type,amount,description,date,source_name,destination_name,category\n"+
"Withdrawal,-123.45,\"foo bar\t#test\",2024-09-01T12:34:56+08:00,\"Test Account\",\"A expense account\",\"Test Category\"\n"), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte("type,amount,description,date,source_name,destination_name,category\n"+
"Withdrawal,-123.45,\"foo bar\t#test\",2024-09-01T12:34:56+08:00,\"Test Account\",\"A expense account\",\"Test Category\"\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
assert.Equal(t, "foo bar\t#test", allNewTransactions[0].Comment)
}
func TestFireFlyIIICsvFileConverterParseImportedData_ParseTags(t *testing.T) {
converter := FireflyIIITransactionDataCsvFileImporter
func TestFireFlyIIICsvFileimporterParseImportedData_ParseTags(t *testing.T) {
importer := FireflyIIITransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -314,8 +315,8 @@ func TestFireFlyIIICsvFileConverterParseImportedData_ParseTags(t *testing.T) {
DefaultCurrency: "CNY",
}
allNewTransactions, _, _, _, _, allNewTags, err := converter.ParseImportedData(context, user, []byte("type,amount,tags,date,source_name,destination_name,category\n"+
"Withdrawal,-123.45,\"tag1,tag2,tag3\",2024-09-01T12:34:56+08:00,\"Test Account\",\"A expense account\",\"Test Category\"\n"), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, allNewTags, err := importer.ParseImportedData(context, user, []byte("type,amount,tags,date,source_name,destination_name,category\n"+
"Withdrawal,-123.45,\"tag1,tag2,tag3\",2024-09-01T12:34:56+08:00,\"Test Account\",\"A expense account\",\"Test Category\"\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
@@ -328,8 +329,8 @@ func TestFireFlyIIICsvFileConverterParseImportedData_ParseTags(t *testing.T) {
assert.Equal(t, "tag3", allNewTags[2].Name)
}
func TestFireFlyIIICsvFileConverterParseImportedData_MissingFileHeader(t *testing.T) {
converter := FireflyIIITransactionDataCsvFileImporter
func TestFireFlyIIICsvFileimporterParseImportedData_MissingFileHeader(t *testing.T) {
importer := FireflyIIITransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -337,12 +338,12 @@ func TestFireFlyIIICsvFileConverterParseImportedData_MissingFileHeader(t *testin
DefaultCurrency: "CNY",
}
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(""), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(""), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrNotFoundTransactionDataInFile.Message)
}
func TestFireFlyIIICsvFileConverterParseImportedData_MissingRequiredColumn(t *testing.T) {
converter := FireflyIIITransactionDataCsvFileImporter
func TestFireFlyIIICsvFileimporterParseImportedData_MissingRequiredColumn(t *testing.T) {
importer := FireflyIIITransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -351,32 +352,32 @@ func TestFireFlyIIICsvFileConverterParseImportedData_MissingRequiredColumn(t *te
}
// Missing Time Column
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte("type,amount,source_name,destination_name,category\n"+
"\"Opening balance\",123.45,\"Initial balance for \"\"Test Account\"\"\",\"Test Account\",\n"), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte("type,amount,source_name,destination_name,category\n"+
"\"Opening balance\",123.45,\"Initial balance for \"\"Test Account\"\"\",\"Test Account\",\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrMissingRequiredFieldInHeaderRow.Message)
// Missing Type Column
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte("amount,date,source_name,destination_name,category\n"+
"123.45,2024-09-01T00:00:00+08:00,\"Initial balance for \"\"Test Account\"\"\",\"Test Account\",\n"), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte("amount,date,source_name,destination_name,category\n"+
"123.45,2024-09-01T00:00:00+08:00,\"Initial balance for \"\"Test Account\"\"\",\"Test Account\",\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrMissingRequiredFieldInHeaderRow.Message)
// Missing Sub Category Column
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte("type,amount,date,source_name,destination_name\n"+
"\"Opening balance\",123.45,2024-09-01T00:00:00+08:00,\"Initial balance for \"\"Test Account\"\"\",\"Test Account\"\n"), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte("type,amount,date,source_name,destination_name\n"+
"\"Opening balance\",123.45,2024-09-01T00:00:00+08:00,\"Initial balance for \"\"Test Account\"\"\",\"Test Account\"\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrMissingRequiredFieldInHeaderRow.Message)
// Missing Account Name Column
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte("type,amount,date,destination_name,category\n"+
"\"Opening balance\",123.45,2024-09-01T00:00:00+08:00,\"Test Account\",\n"), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte("type,amount,date,destination_name,category\n"+
"\"Opening balance\",123.45,2024-09-01T00:00:00+08:00,\"Test Account\",\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrMissingRequiredFieldInHeaderRow.Message)
// Missing Amount Column
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte("type,date,source_name,destination_name,category\n"+
"\"Opening balance\",2024-09-01T00:00:00+08:00,\"Initial balance for \"\"Test Account\"\"\",\"Test Account\",\n"), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte("type,date,source_name,destination_name,category\n"+
"\"Opening balance\",2024-09-01T00:00:00+08:00,\"Initial balance for \"\"Test Account\"\"\",\"Test Account\",\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrMissingRequiredFieldInHeaderRow.Message)
// Missing Account2 Name Column
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte("type,amount,date,source_name,category\n"+
"\"Opening balance\",123.45,2024-09-01T00:00:00+08:00,\"Initial balance for \"\"Test Account\"\"\",\n"), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte("type,amount,date,source_name,category\n"+
"\"Opening balance\",123.45,2024-09-01T00:00:00+08:00,\"Initial balance for \"\"Test Account\"\"\",\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrMissingRequiredFieldInHeaderRow.Message)
}

View File

@@ -24,7 +24,7 @@ var (
)
// ParseImportedData returns the imported data by parsing the gnucash transaction data
func (c *gnucashTransactionDataImporter) ParseImportedData(ctx core.Context, user *models.User, data []byte, defaultTimezoneOffset int16, accountMap map[string]*models.Account, expenseCategoryMap map[string]map[string]*models.TransactionCategory, incomeCategoryMap map[string]map[string]*models.TransactionCategory, transferCategoryMap map[string]map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionTag, error) {
func (c *gnucashTransactionDataImporter) ParseImportedData(ctx core.Context, user *models.User, data []byte, defaultTimezoneOffset int16, additionalOptions converter.TransactionDataImporterOptions, accountMap map[string]*models.Account, expenseCategoryMap map[string]map[string]*models.TransactionCategory, incomeCategoryMap map[string]map[string]*models.TransactionCategory, transferCategoryMap map[string]map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionTag, error) {
gnucashDataReader, err := createNewGnuCashDatabaseReader(data)
if err != nil {
@@ -45,5 +45,5 @@ func (c *gnucashTransactionDataImporter) ParseImportedData(ctx core.Context, use
dataTableImporter := converter.CreateNewSimpleImporterWithTypeNameMapping(gnucashTransactionTypeNameMapping)
return dataTableImporter.ParseImportedData(ctx, user, transactionDataTable, defaultTimezoneOffset, accountMap, expenseCategoryMap, incomeCategoryMap, transferCategoryMap, tagMap)
return dataTableImporter.ParseImportedData(ctx, user, transactionDataTable, defaultTimezoneOffset, additionalOptions, accountMap, expenseCategoryMap, incomeCategoryMap, transferCategoryMap, tagMap)
}

View File

@@ -7,6 +7,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/mayswind/ezbookkeeping/pkg/converters/converter"
"github.com/mayswind/ezbookkeeping/pkg/core"
"github.com/mayswind/ezbookkeeping/pkg/errs"
"github.com/mayswind/ezbookkeeping/pkg/models"
@@ -185,7 +186,7 @@ const gnucashCommonValidDataCaseFooter = "</gnc:book>\n" +
"</gnc-v2>\n"
func TestGnuCashTransactionDatabaseFileParseImportedData_MinimumValidData(t *testing.T) {
converter := GnuCashTransactionDataImporter
importer := GnuCashTransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -193,14 +194,14 @@ func TestGnuCashTransactionDatabaseFileParseImportedData_MinimumValidData(t *tes
DefaultCurrency: "CNY",
}
allNewTransactions, allNewAccounts, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, allNewTags, err := converter.ParseImportedData(context, user, []byte(gnucashMinimumValidDataCase), 0, nil, nil, nil, nil, nil)
allNewTransactions, allNewAccounts, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, allNewTags, err := importer.ParseImportedData(context, user, []byte(gnucashMinimumValidDataCase), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
checkParsedMinimumValidData(t, allNewTransactions, allNewAccounts, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, allNewTags)
}
func TestGnuCashTransactionDatabaseFileParseImportedData_GzippedMinimumValidData(t *testing.T) {
converter := GnuCashTransactionDataImporter
importer := GnuCashTransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -217,14 +218,14 @@ func TestGnuCashTransactionDatabaseFileParseImportedData_GzippedMinimumValidData
assert.Nil(t, err)
gzippedData := buffer.Bytes()
allNewTransactions, allNewAccounts, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, allNewTags, err := converter.ParseImportedData(context, user, gzippedData, 0, nil, nil, nil, nil, nil)
allNewTransactions, allNewAccounts, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, allNewTags, err := importer.ParseImportedData(context, user, gzippedData, 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
checkParsedMinimumValidData(t, allNewTransactions, allNewAccounts, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, allNewTags)
}
func TestGnuCashTransactionDatabaseFileParseImportedData_MinimumValidDataWithReversedSplitOrder(t *testing.T) {
converter := GnuCashTransactionDataImporter
importer := GnuCashTransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -232,7 +233,7 @@ func TestGnuCashTransactionDatabaseFileParseImportedData_MinimumValidDataWithRev
DefaultCurrency: "CNY",
}
allNewTransactions, allNewAccounts, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, allNewTags, err := converter.ParseImportedData(context, user, []byte("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"+
allNewTransactions, allNewAccounts, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, allNewTags, err := importer.ParseImportedData(context, user, []byte("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"+
"<gnc-v2\n"+
" xmlns:gnc=\"http://www.gnucash.org/XML/gnc\"\n"+
" xmlns:act=\"http://www.gnucash.org/XML/act\"\n"+
@@ -356,14 +357,14 @@ func TestGnuCashTransactionDatabaseFileParseImportedData_MinimumValidDataWithRev
" </trn:splits>\n"+
"</gnc:transaction>\n"+
"</gnc:book>\n"+
"</gnc-v2>\n"), 0, nil, nil, nil, nil, nil)
"</gnc-v2>\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
checkParsedMinimumValidData(t, allNewTransactions, allNewAccounts, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, allNewTags)
}
func TestGnuCashTransactionDatabaseFileParseImportedData_ParseInvalidTime(t *testing.T) {
converter := GnuCashTransactionDataImporter
importer := GnuCashTransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -371,7 +372,7 @@ func TestGnuCashTransactionDatabaseFileParseImportedData_ParseInvalidTime(t *tes
DefaultCurrency: "CNY",
}
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
gnucashCommonValidDataCaseHeader+
"<gnc:transaction version=\"2.0.0\">\n"+
" <trn:date-posted>\n"+
@@ -388,10 +389,10 @@ func TestGnuCashTransactionDatabaseFileParseImportedData_ParseInvalidTime(t *tes
" </trn:split>\n"+
" </trn:splits>\n"+
"</gnc:transaction>\n"+
gnucashCommonValidDataCaseFooter), 0, nil, nil, nil, nil, nil)
gnucashCommonValidDataCaseFooter), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrTransactionTimeInvalid.Message)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
gnucashCommonValidDataCaseHeader+
"<gnc:transaction version=\"2.0.0\">\n"+
" <trn:date-posted>\n"+
@@ -408,12 +409,12 @@ func TestGnuCashTransactionDatabaseFileParseImportedData_ParseInvalidTime(t *tes
" </trn:split>\n"+
" </trn:splits>\n"+
"</gnc:transaction>\n"+
gnucashCommonValidDataCaseFooter), 0, nil, nil, nil, nil, nil)
gnucashCommonValidDataCaseFooter), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrTransactionTimeInvalid.Message)
}
func TestGnuCashTransactionDatabaseFileParseImportedData_ParseValidTimezone(t *testing.T) {
converter := GnuCashTransactionDataImporter
importer := GnuCashTransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -421,7 +422,7 @@ func TestGnuCashTransactionDatabaseFileParseImportedData_ParseValidTimezone(t *t
DefaultCurrency: "CNY",
}
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
gnucashCommonValidDataCaseHeader+
"<gnc:transaction version=\"2.0.0\">\n"+
" <trn:date-posted>\n"+
@@ -438,12 +439,12 @@ func TestGnuCashTransactionDatabaseFileParseImportedData_ParseValidTimezone(t *t
" </trn:split>\n"+
" </trn:splits>\n"+
"</gnc:transaction>\n"+
gnucashCommonValidDataCaseFooter), 0, nil, nil, nil, nil, nil)
gnucashCommonValidDataCaseFooter), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
assert.Equal(t, int64(1725230096), utils.GetUnixTimeFromTransactionTime(allNewTransactions[0].TransactionTime))
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
gnucashCommonValidDataCaseHeader+
"<gnc:transaction version=\"2.0.0\">\n"+
" <trn:date-posted>\n"+
@@ -460,14 +461,14 @@ func TestGnuCashTransactionDatabaseFileParseImportedData_ParseValidTimezone(t *t
" </trn:split>\n"+
" </trn:splits>\n"+
"</gnc:transaction>\n"+
gnucashCommonValidDataCaseFooter), 0, nil, nil, nil, nil, nil)
gnucashCommonValidDataCaseFooter), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
assert.Equal(t, int64(1725148196), utils.GetUnixTimeFromTransactionTime(allNewTransactions[0].TransactionTime))
}
func TestGnuCashTransactionDatabaseFileParseImportedData_ParseValidAccountCurrency(t *testing.T) {
converter := GnuCashTransactionDataImporter
importer := GnuCashTransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -475,7 +476,7 @@ func TestGnuCashTransactionDatabaseFileParseImportedData_ParseValidAccountCurren
DefaultCurrency: "CNY",
}
allNewTransactions, allNewAccounts, _, _, _, _, err := converter.ParseImportedData(context, user, []byte("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"+
allNewTransactions, allNewAccounts, _, _, _, _, err := importer.ParseImportedData(context, user, []byte("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"+
"<gnc-v2\n"+
" xmlns:gnc=\"http://www.gnucash.org/XML/gnc\"\n"+
" xmlns:act=\"http://www.gnucash.org/XML/act\"\n"+
@@ -557,7 +558,7 @@ func TestGnuCashTransactionDatabaseFileParseImportedData_ParseValidAccountCurren
" </trn:splits>\n"+
"</gnc:transaction>\n"+
"</gnc:book>\n"+
"</gnc-v2>\n"), 0, nil, nil, nil, nil, nil)
"</gnc-v2>\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
@@ -574,7 +575,7 @@ func TestGnuCashTransactionDatabaseFileParseImportedData_ParseValidAccountCurren
}
func TestGnuCashTransactionDatabaseFileParseImportedData_ParseValidAmount(t *testing.T) {
converter := GnuCashTransactionDataImporter
importer := GnuCashTransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -582,7 +583,7 @@ func TestGnuCashTransactionDatabaseFileParseImportedData_ParseValidAmount(t *tes
DefaultCurrency: "CNY",
}
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
gnucashCommonValidDataCaseHeader+
"<gnc:transaction version=\"2.0.0\">\n"+
" <trn:date-posted>\n"+
@@ -599,13 +600,13 @@ func TestGnuCashTransactionDatabaseFileParseImportedData_ParseValidAmount(t *tes
" </trn:split>\n"+
" </trn:splits>\n"+
"</gnc:transaction>\n"+
gnucashCommonValidDataCaseFooter), 0, nil, nil, nil, nil, nil)
gnucashCommonValidDataCaseFooter), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
assert.Equal(t, int64(1234500), allNewTransactions[0].Amount)
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
gnucashCommonValidDataCaseHeader+
"<gnc:transaction version=\"2.0.0\">\n"+
" <trn:date-posted>\n"+
@@ -622,7 +623,7 @@ func TestGnuCashTransactionDatabaseFileParseImportedData_ParseValidAmount(t *tes
" </trn:split>\n"+
" </trn:splits>\n"+
"</gnc:transaction>\n"+
gnucashCommonValidDataCaseFooter), 0, nil, nil, nil, nil, nil)
gnucashCommonValidDataCaseFooter), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
@@ -630,7 +631,7 @@ func TestGnuCashTransactionDatabaseFileParseImportedData_ParseValidAmount(t *tes
}
func TestGnuCashTransactionDatabaseFileParseImportedData_ParseInvalidAmount(t *testing.T) {
converter := GnuCashTransactionDataImporter
importer := GnuCashTransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -638,7 +639,7 @@ func TestGnuCashTransactionDatabaseFileParseImportedData_ParseInvalidAmount(t *t
DefaultCurrency: "CNY",
}
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
gnucashCommonValidDataCaseHeader+
"<gnc:transaction version=\"2.0.0\">\n"+
" <trn:date-posted>\n"+
@@ -655,10 +656,10 @@ func TestGnuCashTransactionDatabaseFileParseImportedData_ParseInvalidAmount(t *t
" </trn:split>\n"+
" </trn:splits>\n"+
"</gnc:transaction>\n"+
gnucashCommonValidDataCaseFooter), 0, nil, nil, nil, nil, nil)
gnucashCommonValidDataCaseFooter), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrAmountInvalid.Message)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
gnucashCommonValidDataCaseHeader+
"<gnc:transaction version=\"2.0.0\">\n"+
" <trn:date-posted>\n"+
@@ -675,10 +676,10 @@ func TestGnuCashTransactionDatabaseFileParseImportedData_ParseInvalidAmount(t *t
" </trn:split>\n"+
" </trn:splits>\n"+
"</gnc:transaction>\n"+
gnucashCommonValidDataCaseFooter), 0, nil, nil, nil, nil, nil)
gnucashCommonValidDataCaseFooter), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrAmountInvalid.Message)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
gnucashCommonValidDataCaseHeader+
"<gnc:transaction version=\"2.0.0\">\n"+
" <trn:date-posted>\n"+
@@ -695,12 +696,12 @@ func TestGnuCashTransactionDatabaseFileParseImportedData_ParseInvalidAmount(t *t
" </trn:split>\n"+
" </trn:splits>\n"+
"</gnc:transaction>\n"+
gnucashCommonValidDataCaseFooter), 0, nil, nil, nil, nil, nil)
gnucashCommonValidDataCaseFooter), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrAmountInvalid.Message)
}
func TestGnuCashTransactionDatabaseFileParseImportedData_ParseDescription(t *testing.T) {
converter := GnuCashTransactionDataImporter
importer := GnuCashTransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -708,7 +709,7 @@ func TestGnuCashTransactionDatabaseFileParseImportedData_ParseDescription(t *tes
DefaultCurrency: "CNY",
}
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
gnucashCommonValidDataCaseHeader+
"<gnc:transaction version=\"2.0.0\">\n"+
" <trn:date-posted>\n"+
@@ -726,7 +727,7 @@ func TestGnuCashTransactionDatabaseFileParseImportedData_ParseDescription(t *tes
" </trn:split>\n"+
" </trn:splits>\n"+
"</gnc:transaction>\n"+
gnucashCommonValidDataCaseFooter), 0, nil, nil, nil, nil, nil)
gnucashCommonValidDataCaseFooter), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
@@ -734,7 +735,7 @@ func TestGnuCashTransactionDatabaseFileParseImportedData_ParseDescription(t *tes
}
func TestGnuCashTransactionDatabaseFileParseImportedData_SkipZeroAmountTransaction(t *testing.T) {
converter := GnuCashTransactionDataImporter
importer := GnuCashTransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -742,7 +743,7 @@ func TestGnuCashTransactionDatabaseFileParseImportedData_SkipZeroAmountTransacti
DefaultCurrency: "CNY",
}
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
gnucashCommonValidDataCaseHeader+
"<gnc:transaction version=\"2.0.0\">\n"+
" <trn:date-posted>\n"+
@@ -755,12 +756,12 @@ func TestGnuCashTransactionDatabaseFileParseImportedData_SkipZeroAmountTransacti
" </trn:split>\n"+
" </trn:splits>\n"+
"</gnc:transaction>\n"+
gnucashCommonValidDataCaseFooter), 0, nil, nil, nil, nil, nil)
gnucashCommonValidDataCaseFooter), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrNotFoundTransactionDataInFile.Message)
}
func TestGnuCashTransactionDatabaseFileParseImportedData_NotSupportedToParseSplitTransaction(t *testing.T) {
converter := GnuCashTransactionDataImporter
importer := GnuCashTransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -768,7 +769,7 @@ func TestGnuCashTransactionDatabaseFileParseImportedData_NotSupportedToParseSpli
DefaultCurrency: "CNY",
}
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
gnucashCommonValidDataCaseHeader+
"<gnc:account version=\"2.0.0\">\n"+
" <act:name>Test Category2</act:name>\n"+
@@ -805,12 +806,12 @@ func TestGnuCashTransactionDatabaseFileParseImportedData_NotSupportedToParseSpli
" </trn:split>\n"+
" </trn:splits>\n"+
"</gnc:transaction>\n"+
gnucashCommonValidDataCaseFooter), 0, nil, nil, nil, nil, nil)
gnucashCommonValidDataCaseFooter), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrNotSupportedSplitTransactions.Message)
}
func TestGnuCashTransactionDatabaseFileParseImportedData_MissingAccountRequiredNode(t *testing.T) {
converter := GnuCashTransactionDataImporter
importer := GnuCashTransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -819,7 +820,7 @@ func TestGnuCashTransactionDatabaseFileParseImportedData_MissingAccountRequiredN
}
// Missing Account Currency Node
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"+
"<gnc-v2\n"+
" xmlns:gnc=\"http://www.gnucash.org/XML/gnc\"\n"+
@@ -872,12 +873,12 @@ func TestGnuCashTransactionDatabaseFileParseImportedData_MissingAccountRequiredN
" </trn:split>\n"+
" </trn:splits>\n"+
"</gnc:transaction>\n"+
gnucashCommonValidDataCaseFooter), 0, nil, nil, nil, nil, nil)
gnucashCommonValidDataCaseFooter), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrAccountCurrencyInvalid.Message)
}
func TestGnuCashTransactionDatabaseFileParseImportedData_MissingTransactionRequiredNode(t *testing.T) {
converter := GnuCashTransactionDataImporter
importer := GnuCashTransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -886,7 +887,7 @@ func TestGnuCashTransactionDatabaseFileParseImportedData_MissingTransactionRequi
}
// Missing Transaction Time Node
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
gnucashCommonValidDataCaseHeader+
"<gnc:transaction version=\"2.0.0\">\n"+
" <trn:splits>\n"+
@@ -900,22 +901,22 @@ func TestGnuCashTransactionDatabaseFileParseImportedData_MissingTransactionRequi
" </trn:split>\n"+
" </trn:splits>\n"+
"</gnc:transaction>\n"+
gnucashCommonValidDataCaseFooter), 0, nil, nil, nil, nil, nil)
gnucashCommonValidDataCaseFooter), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrMissingTransactionTime.Message)
// Missing Transaction Splits Node
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
gnucashCommonValidDataCaseHeader+
"<gnc:transaction version=\"2.0.0\">\n"+
" <trn:date-posted>\n"+
" <ts:date>2024-09-01 00:00:00 +0000</ts:date>\n"+
" </trn:date-posted>\n"+
"</gnc:transaction>\n"+
gnucashCommonValidDataCaseFooter), 0, nil, nil, nil, nil, nil)
gnucashCommonValidDataCaseFooter), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrInvalidGnuCashFile.Message)
// Missing Transaction Split Quantity Node
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
gnucashCommonValidDataCaseHeader+
"<gnc:transaction version=\"2.0.0\">\n"+
" <trn:date-posted>\n"+
@@ -930,11 +931,11 @@ func TestGnuCashTransactionDatabaseFileParseImportedData_MissingTransactionRequi
" </trn:split>\n"+
" </trn:splits>\n"+
"</gnc:transaction>\n"+
gnucashCommonValidDataCaseFooter), 0, nil, nil, nil, nil, nil)
gnucashCommonValidDataCaseFooter), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrAmountInvalid.Message)
// Missing Transaction Split Account Node
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
gnucashCommonValidDataCaseHeader+
"<gnc:transaction version=\"2.0.0\">\n"+
" <trn:date-posted>\n"+
@@ -950,7 +951,7 @@ func TestGnuCashTransactionDatabaseFileParseImportedData_MissingTransactionRequi
" </trn:split>\n"+
" </trn:splits>\n"+
"</gnc:transaction>\n"+
gnucashCommonValidDataCaseFooter), 0, nil, nil, nil, nil, nil)
gnucashCommonValidDataCaseFooter), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrMissingAccountData.Message)
}

View File

@@ -23,7 +23,7 @@ var (
)
// ParseImportedData returns the imported data by parsing the intuit interchange format (iif) data
func (c *iifTransactionDataFileImporter) ParseImportedData(ctx core.Context, user *models.User, data []byte, defaultTimezoneOffset int16, accountMap map[string]*models.Account, expenseCategoryMap map[string]map[string]*models.TransactionCategory, incomeCategoryMap map[string]map[string]*models.TransactionCategory, transferCategoryMap map[string]map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionTag, error) {
func (c *iifTransactionDataFileImporter) ParseImportedData(ctx core.Context, user *models.User, data []byte, defaultTimezoneOffset int16, additionalOptions converter.TransactionDataImporterOptions, accountMap map[string]*models.Account, expenseCategoryMap map[string]map[string]*models.TransactionCategory, incomeCategoryMap map[string]map[string]*models.TransactionCategory, transferCategoryMap map[string]map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionTag, error) {
iifDataReader := createNewIifDataReader(data)
accountDatasets, transactionDatasets, err := iifDataReader.read(ctx)
@@ -39,5 +39,5 @@ func (c *iifTransactionDataFileImporter) ParseImportedData(ctx core.Context, use
dataTableImporter := converter.CreateNewSimpleImporterWithTypeNameMapping(iifTransactionTypeNameMapping)
return dataTableImporter.ParseImportedData(ctx, user, transactionDataTable, defaultTimezoneOffset, accountMap, expenseCategoryMap, incomeCategoryMap, transferCategoryMap, tagMap)
return dataTableImporter.ParseImportedData(ctx, user, transactionDataTable, defaultTimezoneOffset, additionalOptions, accountMap, expenseCategoryMap, incomeCategoryMap, transferCategoryMap, tagMap)
}

View File

@@ -5,6 +5,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/mayswind/ezbookkeeping/pkg/converters/converter"
"github.com/mayswind/ezbookkeeping/pkg/core"
"github.com/mayswind/ezbookkeeping/pkg/errs"
"github.com/mayswind/ezbookkeeping/pkg/models"
@@ -12,7 +13,7 @@ import (
)
func TestIIFTransactionDataFileParseImportedData_MinimumValidData(t *testing.T) {
converter := IifTransactionDataFileImporter
importer := IifTransactionDataFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -20,7 +21,7 @@ func TestIIFTransactionDataFileParseImportedData_MinimumValidData(t *testing.T)
DefaultCurrency: "CNY",
}
allNewTransactions, allNewAccounts, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, allNewTags, err := converter.ParseImportedData(context, user, []byte(
allNewTransactions, allNewAccounts, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, allNewTags, err := importer.ParseImportedData(context, user, []byte(
"!ACCNT\tNAME\tACCNTTYPE\n"+
"ACCNT\tTest Account\tBANK\n"+
"ACCNT\tTest Account2\tBANK\n"+
@@ -49,7 +50,7 @@ func TestIIFTransactionDataFileParseImportedData_MinimumValidData(t *testing.T)
"ENDTRNS\t\t\t\t\n"+
"TRNS\tCREDIT CARD\t09/07/2024\tTest Category2\t34.56\n"+
"SPL\tCREDIT CARD\t09/07/2024\tTest Account2\t-34.56\n"+
"ENDTRNS\t\t\t\t\n"), 0, nil, nil, nil, nil, nil)
"ENDTRNS\t\t\t\t\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
@@ -132,7 +133,7 @@ func TestIIFTransactionDataFileParseImportedData_MinimumValidData(t *testing.T)
}
func TestIIFTransactionDataFileParseImportedData_MinimumValidDataWithoutAccountData(t *testing.T) {
converter := IifTransactionDataFileImporter
importer := IifTransactionDataFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -140,13 +141,13 @@ func TestIIFTransactionDataFileParseImportedData_MinimumValidDataWithoutAccountD
DefaultCurrency: "CNY",
}
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"!TRNS\tDATE\tACCNT\tAMOUNT\n"+
"!SPL\tDATE\tACCNT\tAMOUNT\n"+
"!ENDTRNS\t\t\t\n"+
"TRNS\t09/01/2024\tTest Account\t123.45\n"+
"SPL\t09/01/2024\tTest Category\t-123.45\n"+
"ENDTRNS\t\t\t\n"), 0, nil, nil, nil, nil, nil)
"ENDTRNS\t\t\t\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
@@ -162,7 +163,7 @@ func TestIIFTransactionDataFileParseImportedData_MinimumValidDataWithoutAccountD
}
func TestIIFTransactionDataFileParseImportedData_MultipleDataset(t *testing.T) {
converter := IifTransactionDataFileImporter
importer := IifTransactionDataFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -170,7 +171,7 @@ func TestIIFTransactionDataFileParseImportedData_MultipleDataset(t *testing.T) {
DefaultCurrency: "CNY",
}
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"!ACCNT\tNAME\tACCNTTYPE\n"+
"ACCNT\tTest Account3\tBANK\n"+
"ACCNT\tTest Account4\tBANK\n"+
@@ -202,7 +203,7 @@ func TestIIFTransactionDataFileParseImportedData_MultipleDataset(t *testing.T) {
"ENDTRNS\t\t\t\t\n"+
"!ACCNT\tTEST\tNAME\tACCNTTYPE\n"+
"ACCNT\t\tTest Category\tINC\n"+
"ACCNT\t\tTest Category2\tEXP\n"), 0, nil, nil, nil, nil, nil)
"ACCNT\t\tTest Category2\tEXP\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
@@ -247,7 +248,7 @@ func TestIIFTransactionDataFileParseImportedData_MultipleDataset(t *testing.T) {
}
func TestIIFTransactionDataFileParseImportedData_ParseCategoryAndSubCategory(t *testing.T) {
converter := IifTransactionDataFileImporter
importer := IifTransactionDataFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -255,7 +256,7 @@ func TestIIFTransactionDataFileParseImportedData_ParseCategoryAndSubCategory(t *
DefaultCurrency: "CNY",
}
allNewTransactions, _, allNewSubExpenseCategories, allNewSubIncomeCategories, _, _, err := converter.ParseImportedData(context, user, []byte(
allNewTransactions, _, allNewSubExpenseCategories, allNewSubIncomeCategories, _, _, err := importer.ParseImportedData(context, user, []byte(
"!ACCNT\tNAME\tACCNTTYPE\n"+
"ACCNT\tTest Parent Category:Test Category\tINC\n"+
"ACCNT\tTest Parent Category2:Test Category2\tEXP\n"+
@@ -267,7 +268,7 @@ func TestIIFTransactionDataFileParseImportedData_ParseCategoryAndSubCategory(t *
"ENDTRNS\t\t\t\n"+
"TRNS\t09/02/2024\tTest Account2\t-123.45\n"+
"SPL\t09/02/2024\tTest Parent Category2:Test Category2\t123.45\n"+
"ENDTRNS\t\t\t\n"), 0, nil, nil, nil, nil, nil)
"ENDTRNS\t\t\t\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
@@ -299,7 +300,7 @@ func TestIIFTransactionDataFileParseImportedData_ParseCategoryAndSubCategory(t *
}
func TestIIFTransactionDataFileParseImportedData_ParseYearMonthDayFormatTime(t *testing.T) {
converter := IifTransactionDataFileImporter
importer := IifTransactionDataFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -307,7 +308,7 @@ func TestIIFTransactionDataFileParseImportedData_ParseYearMonthDayFormatTime(t *
DefaultCurrency: "CNY",
}
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"!TRNS\tDATE\tACCNT\tAMOUNT\n"+
"!SPL\tDATE\tACCNT\tAMOUNT\n"+
"!ENDTRNS\t\t\t\n"+
@@ -322,7 +323,7 @@ func TestIIFTransactionDataFileParseImportedData_ParseYearMonthDayFormatTime(t *
"ENDTRNS\t\t\t\n"+
"TRNS\t2024/9/4\tTest Account\t123.45\n"+
"SPL\t2024/9/4\tTest Account2\t-123.45\n"+
"ENDTRNS\t\t\t\n"), 0, nil, nil, nil, nil, nil)
"ENDTRNS\t\t\t\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
@@ -334,7 +335,7 @@ func TestIIFTransactionDataFileParseImportedData_ParseYearMonthDayFormatTime(t *
}
func TestIIFTransactionDataFileParseImportedData_ParseShortMonthDayYearFormatTime(t *testing.T) {
converter := IifTransactionDataFileImporter
importer := IifTransactionDataFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -342,7 +343,7 @@ func TestIIFTransactionDataFileParseImportedData_ParseShortMonthDayYearFormatTim
DefaultCurrency: "CNY",
}
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"!TRNS\tDATE\tACCNT\tAMOUNT\n"+
"!SPL\tDATE\tACCNT\tAMOUNT\n"+
"!ENDTRNS\t\t\t\n"+
@@ -354,7 +355,7 @@ func TestIIFTransactionDataFileParseImportedData_ParseShortMonthDayYearFormatTim
"ENDTRNS\t\t\t\n"+
"TRNS\t9/3/2024\tTest Account\t123.45\n"+
"SPL\t9/3/2024\tTest Account2\t-123.45\n"+
"ENDTRNS\t\t\t\n"), 0, nil, nil, nil, nil, nil)
"ENDTRNS\t\t\t\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
@@ -365,7 +366,7 @@ func TestIIFTransactionDataFileParseImportedData_ParseShortMonthDayYearFormatTim
}
func TestIIFTransactionDataFileParseImportedData_ParseShortMonthDayTwoDigitsYearFormatTime(t *testing.T) {
converter := IifTransactionDataFileImporter
importer := IifTransactionDataFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -373,7 +374,7 @@ func TestIIFTransactionDataFileParseImportedData_ParseShortMonthDayTwoDigitsYear
DefaultCurrency: "CNY",
}
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"!TRNS\tDATE\tACCNT\tAMOUNT\n"+
"!SPL\tDATE\tACCNT\tAMOUNT\n"+
"!ENDTRNS\t\t\t\n"+
@@ -385,7 +386,7 @@ func TestIIFTransactionDataFileParseImportedData_ParseShortMonthDayTwoDigitsYear
"ENDTRNS\t\t\t\n"+
"TRNS\t24/9/3\tTest Account\t123.45\n"+
"SPL\t24/9/3\tTest Account2\t-123.45\n"+
"ENDTRNS\t\t\t\n"), 0, nil, nil, nil, nil, nil)
"ENDTRNS\t\t\t\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
@@ -396,7 +397,7 @@ func TestIIFTransactionDataFileParseImportedData_ParseShortMonthDayTwoDigitsYear
}
func TestIIFTransactionDataFileParseImportedData_ParseInvalidTime(t *testing.T) {
converter := IifTransactionDataFileImporter
importer := IifTransactionDataFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -404,36 +405,36 @@ func TestIIFTransactionDataFileParseImportedData_ParseInvalidTime(t *testing.T)
DefaultCurrency: "CNY",
}
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"!TRNS\tDATE\tACCNT\tAMOUNT\n"+
"!SPL\tDATE\tACCNT\tAMOUNT\n"+
"!ENDTRNS\t\t\t\n"+
"TRNS\t09-01-2024\tTest Account\t123.45\n"+
"SPL\t09-01-2024\tTest Account2\t-123.45\n"+
"ENDTRNS\t\t\t\n"), 0, nil, nil, nil, nil, nil)
"ENDTRNS\t\t\t\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrTransactionTimeInvalid.Message)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"!TRNS\tDATE\tACCNT\tAMOUNT\n"+
"!SPL\tDATE\tACCNT\tAMOUNT\n"+
"!ENDTRNS\t\t\t\n"+
"TRNS\t2024-09-01\tTest Account\t123.45\n"+
"SPL\t2024-09-01\tTest Account2\t-123.45\n"+
"ENDTRNS\t\t\t\n"), 0, nil, nil, nil, nil, nil)
"ENDTRNS\t\t\t\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrTransactionTimeInvalid.Message)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"!TRNS\tDATE\tACCNT\tAMOUNT\n"+
"!SPL\tDATE\tACCNT\tAMOUNT\n"+
"!ENDTRNS\t\t\t\n"+
"TRNS\t9/24\tTest Account\t123.45\n"+
"SPL\t9/24\tTest Account2\t-123.45\n"+
"ENDTRNS\t\t\t\n"), 0, nil, nil, nil, nil, nil)
"ENDTRNS\t\t\t\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrTransactionTimeInvalid.Message)
}
func TestIIFTransactionDataFileParseImportedData_ParseAmountWithThousandsSeparator(t *testing.T) {
converter := IifTransactionDataFileImporter
importer := IifTransactionDataFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -441,13 +442,13 @@ func TestIIFTransactionDataFileParseImportedData_ParseAmountWithThousandsSeparat
DefaultCurrency: "CNY",
}
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"!TRNS\tDATE\tACCNT\tAMOUNT\n"+
"!SPL\tDATE\tACCNT\tAMOUNT\n"+
"!ENDTRNS\t\t\t\n"+
"TRNS\t9/01/2024\tTest Account\t123,456.78\n"+
"SPL\t9/01/2024\tTest Account2\t-123,456.78\n"+
"ENDTRNS\t\t\t\n"), 0, nil, nil, nil, nil, nil)
"ENDTRNS\t\t\t\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
@@ -456,7 +457,7 @@ func TestIIFTransactionDataFileParseImportedData_ParseAmountWithThousandsSeparat
}
func TestIIFTransactionDataFileParseImportedData_ParseInvalidAmount(t *testing.T) {
converter := IifTransactionDataFileImporter
importer := IifTransactionDataFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -464,27 +465,27 @@ func TestIIFTransactionDataFileParseImportedData_ParseInvalidAmount(t *testing.T
DefaultCurrency: "CNY",
}
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"!TRNS\tDATE\tACCNT\tAMOUNT\n"+
"!SPL\tDATE\tACCNT\tAMOUNT\n"+
"!ENDTRNS\t\t\t\n"+
"TRNS\t09/01/2024\tTest Account\t123 45\n"+
"SPL\t09/01/2024\tTest Account2\t-123.45\n"+
"ENDTRNS\t\t\t\n"), 0, nil, nil, nil, nil, nil)
"ENDTRNS\t\t\t\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrAmountInvalid.Message)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"!TRNS\tDATE\tACCNT\tAMOUNT\n"+
"!SPL\tDATE\tACCNT\tAMOUNT\n"+
"!ENDTRNS\t\t\t\n"+
"TRNS\t09/01/2024\tTest Account\t123.45\n"+
"SPL\t09/01/2024\tTest Account2\t-123 45\n"+
"ENDTRNS\t\t\t\n"), 0, nil, nil, nil, nil, nil)
"ENDTRNS\t\t\t\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrAmountInvalid.Message)
}
func TestIIFTransactionDataFileParseImportedData_ParseDescription(t *testing.T) {
converter := IifTransactionDataFileImporter
importer := IifTransactionDataFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -492,25 +493,25 @@ func TestIIFTransactionDataFileParseImportedData_ParseDescription(t *testing.T)
DefaultCurrency: "CNY",
}
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"!TRNS\tDATE\tACCNT\tNAME\tAMOUNT\tMEMO\n"+
"!SPL\tDATE\tACCNT\tNAME\tAMOUNT\tMEMO\n"+
"!ENDTRNS\t\t\t\t\t\n"+
"TRNS\t09/01/2024\tTest Account\t\"Test\"\t123.45\t\"foo bar\t#test\"\n"+
"SPL\t09/01/2024\tTest Account2\t\t-123.45\t\n"+
"ENDTRNS\t\t\t\t\t\n"), 0, nil, nil, nil, nil, nil)
"ENDTRNS\t\t\t\t\t\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
assert.Equal(t, "foo bar\t#test", allNewTransactions[0].Comment)
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"!TRNS\tDATE\tACCNT\tNAME\tAMOUNT\tMEMO\n"+
"!SPL\tDATE\tACCNT\tNAME\tAMOUNT\tMEMO\n"+
"!ENDTRNS\t\t\t\t\t\n"+
"TRNS\t09/01/2024\tTest Account\tTest\t123.45\t\n"+
"SPL\t09/01/2024\tTest Account2\t\t-123.45\t\n"+
"ENDTRNS\t\t\t\t\t\n"), 0, nil, nil, nil, nil, nil)
"ENDTRNS\t\t\t\t\t\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
@@ -518,7 +519,7 @@ func TestIIFTransactionDataFileParseImportedData_ParseDescription(t *testing.T)
}
func TestIIFTransactionDataFileParseImportedData_ParseSplitTransaction(t *testing.T) {
converter := IifTransactionDataFileImporter
importer := IifTransactionDataFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -526,7 +527,7 @@ func TestIIFTransactionDataFileParseImportedData_ParseSplitTransaction(t *testin
DefaultCurrency: "CNY",
}
allNewTransactions, allNewAccounts, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
allNewTransactions, allNewAccounts, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"!ACCNT\tNAME\tACCNTTYPE\n"+
"ACCNT\tTest Category\tINC\n"+
"ACCNT\tTest Category2\tEXP\n"+
@@ -552,7 +553,7 @@ func TestIIFTransactionDataFileParseImportedData_ParseSplitTransaction(t *testin
"TRNS\t09/05/2024\tTest Category2\t100.00\n"+
"SPL\t09/05/2024\tTest Account3\t-40.00\n"+
"SPL\t09/05/2024\tTest Account4\t-60.00\n"+
"ENDTRNS\t\t\t\n"), 0, nil, nil, nil, nil, nil)
"ENDTRNS\t\t\t\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
@@ -651,7 +652,7 @@ func TestIIFTransactionDataFileParseImportedData_ParseSplitTransaction(t *testin
}
func TestIIFTransactionDataFileParseImportedData_ParseSplitTransactionDescription(t *testing.T) {
converter := IifTransactionDataFileImporter
importer := IifTransactionDataFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -659,21 +660,21 @@ func TestIIFTransactionDataFileParseImportedData_ParseSplitTransactionDescriptio
DefaultCurrency: "CNY",
}
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"!TRNS\tDATE\tACCNT\tNAME\tAMOUNT\tMEMO\n"+
"!SPL\tDATE\tACCNT\tNAME\tAMOUNT\tMEMO\n"+
"!ENDTRNS\t\t\t\t\t\n"+
"TRNS\t09/01/2024\tTest Account\t\"Test\"\t123.45\t\"foo bar\t#test\"\n"+
"SPL\t09/01/2024\tTest Account2\t\t-100.00\t\"foo\ttest#bar\"\n"+
"SPL\t09/01/2024\tTest Account3\t\t-23.45\t\n"+
"ENDTRNS\t\t\t\t\t\n"), 0, nil, nil, nil, nil, nil)
"ENDTRNS\t\t\t\t\t\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 2, len(allNewTransactions))
assert.Equal(t, "foo\ttest#bar", allNewTransactions[0].Comment)
assert.Equal(t, "foo bar\t#test", allNewTransactions[1].Comment)
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"!TRNS\tDATE\tACCNT\tNAME\tAMOUNT\tMEMO\n"+
"!SPL\tDATE\tACCNT\tNAME\tAMOUNT\tMEMO\n"+
"!ENDTRNS\t\t\t\t\t\n"+
@@ -681,7 +682,7 @@ func TestIIFTransactionDataFileParseImportedData_ParseSplitTransactionDescriptio
"SPL\t09/01/2024\tTest Account2\t\t-100.00\t\"test\"\n"+
"SPL\t09/01/2024\tTest Account3\tfoo\t-12.34\t\n"+
"SPL\t09/01/2024\tTest Account4\t\t-11.11\t\n"+
"ENDTRNS\t\t\t\t\t\n"), 0, nil, nil, nil, nil, nil)
"ENDTRNS\t\t\t\t\t\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 3, len(allNewTransactions))
@@ -691,7 +692,7 @@ func TestIIFTransactionDataFileParseImportedData_ParseSplitTransactionDescriptio
}
func TestIIFTransactionDataFileParseImportedData_NotSupportedSplitTransaction(t *testing.T) {
converter := IifTransactionDataFileImporter
importer := IifTransactionDataFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -700,52 +701,52 @@ func TestIIFTransactionDataFileParseImportedData_NotSupportedSplitTransaction(t
}
// Opening balance transaction
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"!TRNS\tTRNSTYPE\tDATE\tACCNT\tAMOUNT\n"+
"!SPL\tTRNSTYPE\tDATE\tACCNT\tAMOUNT\n"+
"!ENDTRNS\t\t\t\t\n"+
"TRNS\tBEGINBALCHECK\t09/01/2024\tTest Account\t123.45\n"+
"SPL\tBEGINBALCHECK\t09/01/2024\tTest Account2\t-100.00\n"+
"SPL\tBEGINBALCHECK\t09/01/2024\tTest Account3\t-23.45\n"+
"ENDTRNS\t\t\t\n"), 0, nil, nil, nil, nil, nil)
"ENDTRNS\t\t\t\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrNotSupportedSplitTransactions.Message)
// Transaction with invalid amount
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"!TRNS\tDATE\tACCNT\tAMOUNT\n"+
"!SPL\tDATE\tACCNT\tAMOUNT\n"+
"!ENDTRNS\t\t\t\n"+
"TRNS\t09/01/2024\tTest Account\t123 45\n"+
"SPL\t09/01/2024\tTest Account2\t-100.00\n"+
"SPL\t09/01/2024\tTest Account3\t-23.45\n"+
"ENDTRNS\t\t\t\n"), 0, nil, nil, nil, nil, nil)
"ENDTRNS\t\t\t\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrAmountInvalid.Message)
// Transaction split data with invalid amount
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"!TRNS\tDATE\tACCNT\tAMOUNT\n"+
"!SPL\tDATE\tACCNT\tAMOUNT\n"+
"!ENDTRNS\t\t\t\n"+
"TRNS\t09/01/2024\tTest Account\t123.45\n"+
"SPL\t09/01/2024\tTest Account2\t-100 00\n"+
"SPL\t09/01/2024\tTest Account3\t-23.45\n"+
"ENDTRNS\t\t\t\n"), 0, nil, nil, nil, nil, nil)
"ENDTRNS\t\t\t\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrAmountInvalid.Message)
// Transaction amount not equal to sum of split data amount
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"!TRNS\tDATE\tACCNT\tAMOUNT\n"+
"!SPL\tDATE\tACCNT\tAMOUNT\n"+
"!ENDTRNS\t\t\t\n"+
"TRNS\t09/01/2024\tTest Account\t123.00\n"+
"SPL\t09/01/2024\tTest Account2\t-100.00\n"+
"SPL\t09/01/2024\tTest Account3\t-23.45\n"+
"ENDTRNS\t\t\t\n"), 0, nil, nil, nil, nil, nil)
"ENDTRNS\t\t\t\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrNotSupportedSplitTransactions.Message)
}
func TestIIFTransactionDataFileParseImportedData_InvalidDataLines(t *testing.T) {
converter := IifTransactionDataFileImporter
importer := IifTransactionDataFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -754,75 +755,75 @@ func TestIIFTransactionDataFileParseImportedData_InvalidDataLines(t *testing.T)
}
//Missing Transaction Line
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"!TRNS\tDATE\tACCNT\tAMOUNT\n"+
"!SPL\tDATE\tACCNT\tAMOUNT\n"+
"!ENDTRNS\t\t\t\n"+
"SPL\t09/01/2024\tTest Account2\t-123.45\n"+
"ENDTRNS\t\t\t\n"), 0, nil, nil, nil, nil, nil)
"ENDTRNS\t\t\t\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrInvalidIIFFile.Message)
// Missing Transaction And Split Line
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"!TRNS\tDATE\tACCNT\tAMOUNT\n"+
"!SPL\tDATE\tACCNT\tAMOUNT\n"+
"!ENDTRNS\t\t\t\n"+
"ENDTRNS\t\t\t\n"), 0, nil, nil, nil, nil, nil)
"ENDTRNS\t\t\t\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrInvalidIIFFile.Message)
// Missing Split Line
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"!TRNS\tDATE\tACCNT\tAMOUNT\n"+
"!SPL\tDATE\tACCNT\tAMOUNT\n"+
"!ENDTRNS\t\t\t\n"+
"TRNS\t09/01/2024\tTest Account\t123.45\n"+
"ENDTRNS\t\t\t\n"), 0, nil, nil, nil, nil, nil)
"ENDTRNS\t\t\t\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrInvalidIIFFile.Message)
// Missing Transaction End Line
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"!TRNS\tDATE\tACCNT\tAMOUNT\n"+
"!SPL\tDATE\tACCNT\tAMOUNT\n"+
"!ENDTRNS\t\t\t\n"+
"TRNS\t09/01/2024\tTest Account\t123.45\n"+
"SPL\t09/01/2024\tTest Account2\t-123.45\n"), 0, nil, nil, nil, nil, nil)
"SPL\t09/01/2024\tTest Account2\t-123.45\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrInvalidIIFFile.Message)
// Missing Transaction End Line (following is another header)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"!TRNS\tDATE\tACCNT\tAMOUNT\n"+
"!SPL\tDATE\tACCNT\tAMOUNT\n"+
"!ENDTRNS\t\t\t\n"+
"TRNS\t09/01/2024\tTest Account\t123.45\n"+
"SPL\t09/01/2024\tTest Account2\t-123.45\n"+
"!ACCNT\tNAME\tACCNTTYPE\n"+
"ACCNT\tTest Account\tBANK\n"), 0, nil, nil, nil, nil, nil)
"ACCNT\tTest Account\tBANK\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrInvalidIIFFile.Message)
// Invalid Line
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"!TRNS\tDATE\tACCNT\tAMOUNT\n"+
"!SPL\tDATE\tACCNT\tAMOUNT\n"+
"!ENDTRNS\t\t\t\n"+
"TRNS\t09/01/2024\tTest Account\t123.45\n"+
"SPL\t09/01/2024\tTest Account2\t-123.45\n"+
"TEST\t\t\t\n"+
"ENDTRNS\t\t\t\n"), 0, nil, nil, nil, nil, nil)
"ENDTRNS\t\t\t\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrInvalidIIFFile.Message)
// Repeat Transaction Line
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"!TRNS\tDATE\tACCNT\tAMOUNT\n"+
"!SPL\tDATE\tACCNT\tAMOUNT\n"+
"!ENDTRNS\t\t\t\n"+
"TRNS\t09/01/2024\tTest Account\t123.45\n"+
"TRNS\t09/01/2024\tTest Account\t123.45\n"+
"SPL\t09/01/2024\tTest Account2\t-123.45\n"+
"ENDTRNS\t\t\t\n"), 0, nil, nil, nil, nil, nil)
"ENDTRNS\t\t\t\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrInvalidIIFFile.Message)
// Repeat Transaction End Line
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"!TRNS\tDATE\tACCNT\tAMOUNT\t\n"+
"!SPL\tDATE\tACCNT\tAMOUNT\t\n"+
"!ENDTRNS\t\t\t\n"+
@@ -830,12 +831,12 @@ func TestIIFTransactionDataFileParseImportedData_InvalidDataLines(t *testing.T)
"TRNS\t09/01/2024\tTest Account\t123.45\n"+
"SPL\t09/01/2024\tTest Account2\t-123.45\n"+
"ENDTRNS\t\t\t\n"+
"ENDTRNS\t\t\t\n"), 0, nil, nil, nil, nil, nil)
"ENDTRNS\t\t\t\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrInvalidIIFFile.Message)
}
func TestIIFTransactionDataFileParseImportedData_InvalidHeaderLines(t *testing.T) {
converter := IifTransactionDataFileImporter
importer := IifTransactionDataFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -844,49 +845,49 @@ func TestIIFTransactionDataFileParseImportedData_InvalidHeaderLines(t *testing.T
}
// Missing All Sample Lines
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"TRNS\t09/01/2024\tTest Account\t123.45\n"+
"SPL\t09/01/2024\tTest Account2\t-123.45\n"+
"ENDTRNS\t\t\t\n"), 0, nil, nil, nil, nil, nil)
"ENDTRNS\t\t\t\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrInvalidIIFFile.Message)
// Missing Transaction Sample Line
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"!SPL\tDATE\tACCNT\tAMOUNT\n"+
"!ENDTRNS\t\t\t\n"), 0, nil, nil, nil, nil, nil)
"!ENDTRNS\t\t\t\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrInvalidIIFFile.Message)
// Missing Split Sample Line
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"!TRNS\tDATE\tACCNT\tAMOUNT\n"+
"!ENDTRNS\t\t\t\n"), 0, nil, nil, nil, nil, nil)
"!ENDTRNS\t\t\t\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrInvalidIIFFile.Message)
// Missing Transaction End Sample Line
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"!TRNS\tDATE\tACCNT\tAMOUNT\n"+
"!SPL\tDATE\tACCNT\tAMOUNT\n"), 0, nil, nil, nil, nil, nil)
"!SPL\tDATE\tACCNT\tAMOUNT\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrInvalidIIFFile.Message)
// Missing Transaction End Sample Line (following is data line)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"!TRNS\tDATE\tACCNT\tAMOUNT\n"+
"!SPL\tDATE\tACCNT\tAMOUNT\n"+
"TRNS\t09/01/2024\tTest Account\t123.45\n"+
"SPL\t09/01/2024\tTest Account2\t-123.45\n"+
"ENDTRNS\t\t\t\n"), 0, nil, nil, nil, nil, nil)
"ENDTRNS\t\t\t\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrInvalidIIFFile.Message)
// Invalid Sample Line
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"!TRNS\tDATE\tACCNT\tAMOUNT\n"+
"!TEST\tDATE\tACCNT\tAMOUNT\n"+
"!ENDTRNS\t\t\t\n"), 0, nil, nil, nil, nil, nil)
"!ENDTRNS\t\t\t\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrInvalidIIFFile.Message)
}
func TestIIFTransactionDataFileParseImportedData_MissingRequiredColumn(t *testing.T) {
converter := IifTransactionDataFileImporter
importer := IifTransactionDataFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -895,32 +896,32 @@ func TestIIFTransactionDataFileParseImportedData_MissingRequiredColumn(t *testin
}
// Missing Date Column
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"!TRNS\tACCNT\tAMOUNT\t\n"+
"!SPL\tACCNT\tAMOUNT\t\n"+
"!ENDTRNS\t\t\t\n"+
"TRNS\tTest Account\t123.45\n"+
"SPL\tTest Account2\t-123.45\n"+
"ENDTRNS\t\t\t\t\n"), 0, nil, nil, nil, nil, nil)
"ENDTRNS\t\t\t\t\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrMissingRequiredFieldInHeaderRow.Message)
// Missing Account Column
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"!TRNS\tDATE\tAMOUNT\t\n"+
"!SPL\tDATE\tAMOUNT\t\n"+
"!ENDTRNS\t\t\t\n"+
"TRNS\t09/01/2024\t123.45\n"+
"SPL\t09/01/2024\t-123.45\n"+
"ENDTRNS\t\t\t\t\n"), 0, nil, nil, nil, nil, nil)
"ENDTRNS\t\t\t\t\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrMissingRequiredFieldInHeaderRow.Message)
// Missing Amount Column
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"!TRNS\tDATE\tACCNT\t\n"+
"!SPL\tDATE\tACCNT\t\n"+
"!ENDTRNS\t\t\t\n"+
"TRNS\t09/01/2024\tTest Account\n"+
"SPL\t09/01/2024\tTest Account2\n"+
"ENDTRNS\t\t\t\t\n"), 0, nil, nil, nil, nil, nil)
"ENDTRNS\t\t\t\t\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrMissingRequiredFieldInHeaderRow.Message)
}

View File

@@ -27,7 +27,7 @@ var (
)
// ParseImportedData returns the imported data by parsing the jd.com finance transaction csv data
func (c *jdComFinanceTransactionDataCsvFileImporter) ParseImportedData(ctx core.Context, user *models.User, data []byte, defaultTimezoneOffset int16, accountMap map[string]*models.Account, expenseCategoryMap map[string]map[string]*models.TransactionCategory, incomeCategoryMap map[string]map[string]*models.TransactionCategory, transferCategoryMap map[string]map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionTag, error) {
func (c *jdComFinanceTransactionDataCsvFileImporter) ParseImportedData(ctx core.Context, user *models.User, data []byte, defaultTimezoneOffset int16, additionalOptions converter.TransactionDataImporterOptions, accountMap map[string]*models.Account, expenseCategoryMap map[string]map[string]*models.TransactionCategory, incomeCategoryMap map[string]map[string]*models.TransactionCategory, transferCategoryMap map[string]map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionTag, error) {
fallback := unicode.UTF8.NewDecoder()
reader := transform.NewReader(bytes.NewReader(data), unicode.BOMOverride(fallback))
@@ -60,5 +60,5 @@ func (c *jdComFinanceTransactionDataCsvFileImporter) ParseImportedData(ctx core.
transactionDataTable := datatable.CreateNewTransactionDataTableFromCommonDataTable(commonDataTable, jdComFinanceTransactionSupportedColumns, transactionRowParser)
dataTableImporter := converter.CreateNewSimpleImporterWithTypeNameMapping(jdComFinanceTransactionTypeNameMapping)
return dataTableImporter.ParseImportedData(ctx, user, transactionDataTable, defaultTimezoneOffset, accountMap, expenseCategoryMap, incomeCategoryMap, transferCategoryMap, tagMap)
return dataTableImporter.ParseImportedData(ctx, user, transactionDataTable, defaultTimezoneOffset, additionalOptions, accountMap, expenseCategoryMap, incomeCategoryMap, transferCategoryMap, tagMap)
}

View File

@@ -6,6 +6,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/mayswind/ezbookkeeping/pkg/converters/converter"
"github.com/mayswind/ezbookkeeping/pkg/core"
"github.com/mayswind/ezbookkeeping/pkg/errs"
"github.com/mayswind/ezbookkeeping/pkg/models"
@@ -13,7 +14,7 @@ import (
)
func TestJDComFinanceCsvFileImporterParseImportedData_MinimumValidData(t *testing.T) {
converter := JDComFinanceTransactionDataCsvFileImporter
importer := JDComFinanceTransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -30,7 +31,7 @@ func TestJDComFinanceCsvFileImporterParseImportedData_MinimumValidData(t *testin
"2025-09-01 12:34:56,xxx,xxx,123.45,银行卡,交易成功,支出,其他网购\n" +
"2025-09-01 23:59:59,xxx,京东钱包余额充值,0.05,银行卡,交易成功,不计收支,余额\n" +
"2025-09-02 23:59:59,xxx,京东余额提现,0.03,银行卡,交易成功,不计收支,余额\n"
allNewTransactions, allNewAccounts, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, allNewTags, err := converter.ParseImportedData(context, user, []byte(data), 0, nil, nil, nil, nil, nil)
allNewTransactions, allNewAccounts, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, allNewTags, err := importer.ParseImportedData(context, user, []byte(data), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 4, len(allNewTransactions))
@@ -93,7 +94,7 @@ func TestJDComFinanceCsvFileImporterParseImportedData_MinimumValidData(t *testin
}
func TestJDComFinanceCsvFileImporterParseImportedData_ParseRefundTransaction(t *testing.T) {
converter := JDComFinanceTransactionDataCsvFileImporter
importer := JDComFinanceTransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -110,7 +111,7 @@ func TestJDComFinanceCsvFileImporterParseImportedData_ParseRefundTransaction(t *
"2025-09-01 02:34:56,xxx,xxx,0.12(已全额退款),银行卡,交易成功,不计收支\n" +
"2025-09-02 01:23:45,xxx,xxx,3.45,银行卡,退款成功,不计收支\n" +
"2025-09-02 02:34:56,xxx,xxx,123.45(已退款3.45),银行卡,交易成功,支出\n"
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(data1), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(data1), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, int64(1234567890), allNewTransactions[0].Uid)
@@ -139,7 +140,7 @@ func TestJDComFinanceCsvFileImporterParseImportedData_ParseRefundTransaction(t *
}
func TestJDComFinanceCsvFileImporterParseImportedData_ParseInvalidTime(t *testing.T) {
converter := JDComFinanceTransactionDataCsvFileImporter
importer := JDComFinanceTransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -153,7 +154,7 @@ func TestJDComFinanceCsvFileImporterParseImportedData_ParseInvalidTime(t *testin
"\n" +
"交易时间,商户名称,交易说明,金额,收/付款方式,交易状态,收/支\n" +
"2025-09-01T01:23:45,xxx,xxx,0.12,银行卡,交易成功,支出\n"
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(data1), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(data1), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrTransactionTimeInvalid.Message)
data2 := "导出信息:\n" +
@@ -162,12 +163,12 @@ func TestJDComFinanceCsvFileImporterParseImportedData_ParseInvalidTime(t *testin
"\n" +
"交易时间,商户名称,交易说明,金额,收/付款方式,交易状态,收/支\n" +
"09/01/2025 01:23:45,xxx,xxx,0.12,银行卡,交易成功,支出\n"
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data2), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(data2), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrTransactionTimeInvalid.Message)
}
func TestJDComFinanceCsvFileImporterParseImportedData_ParseInvalidType(t *testing.T) {
converter := JDComFinanceTransactionDataCsvFileImporter
importer := JDComFinanceTransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -181,12 +182,12 @@ func TestJDComFinanceCsvFileImporterParseImportedData_ParseInvalidType(t *testin
"\n" +
"交易时间,商户名称,交易说明,金额,收/付款方式,交易状态,收/支\n" +
"2025-09-01 01:23:45,xxx,xxx,0.12,银行卡,交易成功,转账\n"
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(data), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(data), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrNotFoundTransactionDataInFile.Message)
}
func TestJDComFinanceCsvFileImporterParseImportedData_ParseInvalidAmount(t *testing.T) {
converter := JDComFinanceTransactionDataCsvFileImporter
importer := JDComFinanceTransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -200,12 +201,12 @@ func TestJDComFinanceCsvFileImporterParseImportedData_ParseInvalidAmount(t *test
"\n" +
"交易时间,商户名称,交易说明,金额,收/付款方式,交易状态,收/支\n" +
"2025-09-01 01:23:45,xxx,xxx,¥0.12,银行卡,交易成功,支出\n"
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(data), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(data), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrAmountInvalid.Message)
}
func TestJDComFinanceCsvFileImporterParseImportedData_ParseAccountName(t *testing.T) {
converter := JDComFinanceTransactionDataCsvFileImporter
importer := JDComFinanceTransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -220,7 +221,7 @@ func TestJDComFinanceCsvFileImporterParseImportedData_ParseAccountName(t *testin
"\n" +
"交易时间,商户名称,交易说明,金额,收/付款方式,交易状态,收/支,交易分类\n" +
"2025-09-01 01:23:45,xxx,京东钱包余额充值,0.05,银行卡,交易成功,不计收支,余额\n"
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(data1), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(data1), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
@@ -235,7 +236,7 @@ func TestJDComFinanceCsvFileImporterParseImportedData_ParseAccountName(t *testin
"\n" +
"交易时间,商户名称,交易说明,金额,收/付款方式,交易状态,收/支,交易分类\n" +
"2025-09-01 01:23:45,xxx,京东余额提现,0.05,银行卡,交易成功,不计收支,余额\n"
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data2), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(data2), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
@@ -252,7 +253,7 @@ func TestJDComFinanceCsvFileImporterParseImportedData_ParseAccountName(t *testin
"2025-09-01 01:23:45,xxx,京东小金库-转入,0.05,余额,交易成功,不计收支,小金库\n"
assert.Nil(t, err)
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data3), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(data3), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
@@ -269,7 +270,7 @@ func TestJDComFinanceCsvFileImporterParseImportedData_ParseAccountName(t *testin
"2025-09-01 01:23:45,xxx,京东小金库-转出,0.05,余额,交易成功,不计收支,小金库\n"
assert.Nil(t, err)
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data4), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(data4), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
@@ -286,7 +287,7 @@ func TestJDComFinanceCsvFileImporterParseImportedData_ParseAccountName(t *testin
"2025-09-01 01:23:45,xxx,价保退款,0.05,银行卡,交易成功,不计收支,其他\n"
assert.Nil(t, err)
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data5), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(data5), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
@@ -302,7 +303,7 @@ func TestJDComFinanceCsvFileImporterParseImportedData_ParseAccountName(t *testin
"2025-09-01 01:23:45,xxx,白条主动还款,0.05,银行卡,交易成功,不计收支,白条\n"
assert.Nil(t, err)
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data6), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(data6), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
@@ -312,7 +313,7 @@ func TestJDComFinanceCsvFileImporterParseImportedData_ParseAccountName(t *testin
}
func TestJDComFinanceCsvFileImporterParseImportedData_ParseDescription(t *testing.T) {
converter := JDComFinanceTransactionDataCsvFileImporter
importer := JDComFinanceTransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -326,7 +327,7 @@ func TestJDComFinanceCsvFileImporterParseImportedData_ParseDescription(t *testin
"\n" +
"交易时间,商户名称,交易说明,金额,收/付款方式,交易状态,收/支\n" +
"2025-09-01 01:23:45,xxx,,0.12,银行卡,交易成功,支出\n"
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(data1), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(data1), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
@@ -338,7 +339,7 @@ func TestJDComFinanceCsvFileImporterParseImportedData_ParseDescription(t *testin
"\n" +
"交易时间,商户名称,交易说明,交易说明,金额,收/付款方式,交易状态,收/支,备注\n" +
"2025-09-01 01:23:45,xxx,xxx,Test,0.12,银行卡,交易成功,支出,\"foo\"\"bar,\ntest\"\n"
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data2), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(data2), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Equal(t, 1, len(allNewTransactions))
assert.Equal(t, "foo\"bar,\ntest", allNewTransactions[0].Comment)
@@ -348,13 +349,13 @@ func TestJDComFinanceCsvFileImporterParseImportedData_ParseDescription(t *testin
"\n" +
"交易时间,商户名称,交易说明,交易说明,金额,收/付款方式,交易状态,收/支,备注\n" +
"2025-09-01 01:23:45,xxx,xxx,Test,0.12,银行卡,交易成功,支出,\n"
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data3), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(data3), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Equal(t, 1, len(allNewTransactions))
assert.Equal(t, "Test", allNewTransactions[0].Comment)
}
func TestJDComFinanceCsvFileImporterParseImportedData_SkipUnknownStatusTransaction(t *testing.T) {
converter := JDComFinanceTransactionDataCsvFileImporter
importer := JDComFinanceTransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -368,12 +369,12 @@ func TestJDComFinanceCsvFileImporterParseImportedData_SkipUnknownStatusTransacti
"\n" +
"交易时间,商户名称,交易说明,金额,收/付款方式,交易状态,收/支\n" +
"2025-09-01 01:23:45,xxx,xxx,0.12,银行卡,xxxx,支出\n"
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(data), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(data), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrNotFoundTransactionDataInFile.Message)
}
func TestJDComFinanceCsvFileImporterParseImportedData_SkipUnknownMemoTransferTransaction(t *testing.T) {
converter := JDComFinanceTransactionDataCsvFileImporter
importer := JDComFinanceTransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -387,12 +388,12 @@ func TestJDComFinanceCsvFileImporterParseImportedData_SkipUnknownMemoTransferTra
"\n" +
"交易时间,商户名称,交易说明,金额,收/付款方式,交易状态,收/支\n" +
"2025-09-01 01:23:45,xxx,xxx,0.12,银行卡,交易成功,不计收支\n"
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(data), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(data), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrNotFoundTransactionDataInFile.Message)
}
func TestJDComFinanceCsvFileImporterParseImportedData_MissingFileHeader(t *testing.T) {
converter := JDComFinanceTransactionDataCsvFileImporter
importer := JDComFinanceTransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -402,15 +403,15 @@ func TestJDComFinanceCsvFileImporterParseImportedData_MissingFileHeader(t *testi
data := "交易时间,商户名称,交易说明,金额,收/付款方式,交易状态,收/支\n" +
"2025-09-01 01:23:45,xxx,xxx,0.12,银行卡,交易成功,支出\n"
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(data), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(data), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrInvalidFileHeader.Message)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(""), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(""), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrInvalidFileHeader.Message)
}
func TestJDComFinanceCsvFileImporterParseImportedData_MissingRequiredColumn(t *testing.T) {
converter := JDComFinanceTransactionDataCsvFileImporter
importer := JDComFinanceTransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -425,7 +426,7 @@ func TestJDComFinanceCsvFileImporterParseImportedData_MissingRequiredColumn(t *t
"\n" +
"商户名称,交易说明,金额,收/付款方式,交易状态,收/支\n" +
"xxx,xxx,0.12,银行卡,交易成功,支出\n"
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(data1), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(data1), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrInvalidFileHeader.Message)
// Missing Merchant Name Column
@@ -435,7 +436,7 @@ func TestJDComFinanceCsvFileImporterParseImportedData_MissingRequiredColumn(t *t
"\n" +
"交易时间,交易说明,金额,收/付款方式,交易状态,收/支\n" +
"2025-09-01 01:23:45,xxx,0.12,银行卡,交易成功,支出\n"
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data2), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(data2), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrMissingRequiredFieldInHeaderRow.Message)
// Missing Transaction Memo Column
@@ -445,7 +446,7 @@ func TestJDComFinanceCsvFileImporterParseImportedData_MissingRequiredColumn(t *t
"\n" +
"交易时间,商户名称,金额,收/付款方式,交易状态,收/支\n" +
"2025-09-01 01:23:45,xxx,0.12,银行卡,交易成功,支出\n"
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data3), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(data3), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrMissingRequiredFieldInHeaderRow.Message)
// Missing Amount Column
@@ -455,7 +456,7 @@ func TestJDComFinanceCsvFileImporterParseImportedData_MissingRequiredColumn(t *t
"\n" +
"交易时间,商户名称,交易说明,收/付款方式,交易状态,收/支\n" +
"2025-09-01 01:23:45,xxx,xxx,银行卡,交易成功,支出\n"
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data4), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(data4), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrMissingRequiredFieldInHeaderRow.Message)
// Missing Related Account Column
@@ -465,7 +466,7 @@ func TestJDComFinanceCsvFileImporterParseImportedData_MissingRequiredColumn(t *t
"\n" +
"交易时间,商户名称,交易说明,金额,交易状态,收/支\n" +
"2025-09-01 01:23:45,xxx,xxx,0.12,交易成功,支出\n"
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data5), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(data5), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrMissingRequiredFieldInHeaderRow.Message)
// Missing Status Column
@@ -475,7 +476,7 @@ func TestJDComFinanceCsvFileImporterParseImportedData_MissingRequiredColumn(t *t
"\n" +
"交易时间,商户名称,交易说明,金额,收/付款方式,收/支\n" +
"2025-09-01 01:23:45,xxx,xxx,0.12,银行卡,支出\n"
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data6), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(data6), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrMissingRequiredFieldInHeaderRow.Message)
// Missing Type Column
@@ -485,12 +486,12 @@ func TestJDComFinanceCsvFileImporterParseImportedData_MissingRequiredColumn(t *t
"\n" +
"交易时间,商户名称,交易说明,金额,收/付款方式,交易状态\n" +
"2025-09-01 01:23:45,xxx,xxx,0.12,银行卡,交易成功\n"
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data7), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(data7), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrMissingRequiredFieldInHeaderRow.Message)
}
func TestJDComFinanceCsvFileImporterParseImportedData_NoTransactionData(t *testing.T) {
converter := JDComFinanceTransactionDataCsvFileImporter
importer := JDComFinanceTransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -503,6 +504,6 @@ func TestJDComFinanceCsvFileImporterParseImportedData_NoTransactionData(t *testi
"日期区间2025-01-01 至 2025-09-01\n" +
"\n" +
"交易时间,商户名称,交易说明,金额,收/付款方式,交易状态,收/支\n"
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(data), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(data), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrNotFoundTransactionDataInFile.Message)
}

View File

@@ -22,7 +22,7 @@ var (
)
// ParseImportedData returns the imported data by parsing the mt940 file statement data
func (c *mt940TransactionDataFileImporter) ParseImportedData(ctx core.Context, user *models.User, data []byte, defaultTimezoneOffset int16, accountMap map[string]*models.Account, expenseCategoryMap map[string]map[string]*models.TransactionCategory, incomeCategoryMap map[string]map[string]*models.TransactionCategory, transferCategoryMap map[string]map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionTag, error) {
func (c *mt940TransactionDataFileImporter) ParseImportedData(ctx core.Context, user *models.User, data []byte, defaultTimezoneOffset int16, additionalOptions converter.TransactionDataImporterOptions, accountMap map[string]*models.Account, expenseCategoryMap map[string]map[string]*models.TransactionCategory, incomeCategoryMap map[string]map[string]*models.TransactionCategory, transferCategoryMap map[string]map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionTag, error) {
mt940DataReader := createNewMT940FileReader(data)
mt940Data, err := mt940DataReader.read(ctx)
@@ -38,5 +38,5 @@ func (c *mt940TransactionDataFileImporter) ParseImportedData(ctx core.Context, u
dataTableImporter := converter.CreateNewSimpleImporterWithTypeNameMapping(mt940TransactionTypeNameMapping)
return dataTableImporter.ParseImportedData(ctx, user, transactionDataTable, defaultTimezoneOffset, accountMap, expenseCategoryMap, incomeCategoryMap, transferCategoryMap, tagMap)
return dataTableImporter.ParseImportedData(ctx, user, transactionDataTable, defaultTimezoneOffset, additionalOptions, accountMap, expenseCategoryMap, incomeCategoryMap, transferCategoryMap, tagMap)
}

View File

@@ -5,6 +5,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/mayswind/ezbookkeeping/pkg/converters/converter"
"github.com/mayswind/ezbookkeeping/pkg/core"
"github.com/mayswind/ezbookkeeping/pkg/errs"
"github.com/mayswind/ezbookkeeping/pkg/models"
@@ -12,7 +13,7 @@ import (
)
func TestMT940TransactionDataFileParseImportedData_MinimumValidData(t *testing.T) {
converter := MT940TransactionDataFileImporter
importer := MT940TransactionDataFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -20,7 +21,7 @@ func TestMT940TransactionDataFileParseImportedData_MinimumValidData(t *testing.T
DefaultCurrency: "CNY",
}
allNewTransactions, allNewAccounts, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, allNewTags, err := converter.ParseImportedData(context, user, []byte(
allNewTransactions, allNewAccounts, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, allNewTags, err := importer.ParseImportedData(context, user, []byte(
`{1:F01TESTBANK123456789}{2:I940TESTBANK}{4:
:20:123456789
:25:12345678
@@ -31,7 +32,7 @@ func TestMT940TransactionDataFileParseImportedData_MinimumValidData(t *testing.T
:61:2506020603D234,56NTRFFOOBAR
:86:Transaction 2
:62F:C250601CNY123,45
-}`), 0, nil, nil, nil, nil, nil)
-}`), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
@@ -70,7 +71,7 @@ func TestMT940TransactionDataFileParseImportedData_MinimumValidData(t *testing.T
}
func TestMT940TransactionDataFileParseImportedData_ParseTransactionValidAmountAndCurrency(t *testing.T) {
converter := MT940TransactionDataFileImporter
importer := MT940TransactionDataFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -78,7 +79,7 @@ func TestMT940TransactionDataFileParseImportedData_ParseTransactionValidAmountAn
DefaultCurrency: "CNY",
}
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
`{1:F01TESTBANK123456789}{2:I940TESTBANK}{4:
:20:123456789
:25:12345678
@@ -91,7 +92,7 @@ func TestMT940TransactionDataFileParseImportedData_ParseTransactionValidAmountAn
:61:250603C1,NTRFTEST
:86:Transaction 3
:62F:C250601CNY123,45
-}`), 0, nil, nil, nil, nil, nil)
-}`), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 3, len(allNewTransactions))
@@ -101,7 +102,7 @@ func TestMT940TransactionDataFileParseImportedData_ParseTransactionValidAmountAn
}
func TestMT940TransactionDataFileParseImportedData_ParseTransactionInvalidAmountAndCurrency(t *testing.T) {
converter := MT940TransactionDataFileImporter
importer := MT940TransactionDataFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -109,7 +110,7 @@ func TestMT940TransactionDataFileParseImportedData_ParseTransactionInvalidAmount
DefaultCurrency: "CNY",
}
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
`{1:F01TESTBANK123456789}{2:I940TESTBANK}{4:
:20:123456789
:25:12345678
@@ -117,10 +118,10 @@ func TestMT940TransactionDataFileParseImportedData_ParseTransactionInvalidAmount
:60F:C250601CNY123,45
:61:2506010602C123 45NTRFTEST
:62F:C250601CNY123,45
-}`), 0, nil, nil, nil, nil, nil)
-}`), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrInvalidMT940File.Message)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
`{1:F01TESTBANK123456789}{2:I940TESTBANK}{4:
:20:123456789
:25:12345678
@@ -128,12 +129,12 @@ func TestMT940TransactionDataFileParseImportedData_ParseTransactionInvalidAmount
:60F:C250601CNY123,45
:61:2506010602C12.45NTRFTEST
:62F:C250601CNY123,45
-}`), 0, nil, nil, nil, nil, nil)
-}`), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrInvalidMT940File.Message)
}
func TestMT940TransactionDataFileParseImportedData_ParseTransactionType(t *testing.T) {
converter := MT940TransactionDataFileImporter
importer := MT940TransactionDataFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -141,7 +142,7 @@ func TestMT940TransactionDataFileParseImportedData_ParseTransactionType(t *testi
DefaultCurrency: "CNY",
}
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
`{1:F01TESTBANK123456789}{2:I940TESTBANK}{4:
:20:123456789
:25:12345678
@@ -156,7 +157,7 @@ func TestMT940TransactionDataFileParseImportedData_ParseTransactionType(t *testi
:61:250604RD123,45NTRFTEST
:86:Transaction 4
:62F:C250601CNY123,45
-}`), 0, nil, nil, nil, nil, nil)
-}`), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 4, len(allNewTransactions))
@@ -167,7 +168,7 @@ func TestMT940TransactionDataFileParseImportedData_ParseTransactionType(t *testi
}
func TestMT940TransactionDataFileParseImportedData_ParseDescription(t *testing.T) {
converter := MT940TransactionDataFileImporter
importer := MT940TransactionDataFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -175,7 +176,7 @@ func TestMT940TransactionDataFileParseImportedData_ParseDescription(t *testing.T
DefaultCurrency: "CNY",
}
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
`{1:F01TESTBANK123456789}{2:I940TESTBANK}{4:
:20:123456789
:25:12345678
@@ -186,7 +187,7 @@ func TestMT940TransactionDataFileParseImportedData_ParseDescription(t *testing.T
Part 2
Part 3
:62F:C250601CNY123,45
-}`), 0, nil, nil, nil, nil, nil)
-}`), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
@@ -194,7 +195,7 @@ func TestMT940TransactionDataFileParseImportedData_ParseDescription(t *testing.T
}
func TestMT940TransactionDataFileParseImportedData_MissingRequiredField(t *testing.T) {
converter := MT940TransactionDataFileImporter
importer := MT940TransactionDataFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -203,12 +204,12 @@ func TestMT940TransactionDataFileParseImportedData_MissingRequiredField(t *testi
}
// Missing opening balance and closing balance
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
`{1:F01TESTBANK123456789}{2:I940TESTBANK}{4:
:20:123456789
:28C:123/1
:61:250601C123,45NTRFTEST
:86:Transaction 1
-}`), 0, nil, nil, nil, nil, nil)
-}`), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrAccountCurrencyInvalid.Message)
}

View File

@@ -23,7 +23,7 @@ var (
)
// ParseImportedData returns the imported data by parsing the open financial exchange (ofx) file transaction data
func (c *ofxTransactionDataImporter) ParseImportedData(ctx core.Context, user *models.User, data []byte, defaultTimezoneOffset int16, accountMap map[string]*models.Account, expenseCategoryMap map[string]map[string]*models.TransactionCategory, incomeCategoryMap map[string]map[string]*models.TransactionCategory, transferCategoryMap map[string]map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionTag, error) {
func (c *ofxTransactionDataImporter) ParseImportedData(ctx core.Context, user *models.User, data []byte, defaultTimezoneOffset int16, additionalOptions converter.TransactionDataImporterOptions, accountMap map[string]*models.Account, expenseCategoryMap map[string]map[string]*models.TransactionCategory, incomeCategoryMap map[string]map[string]*models.TransactionCategory, transferCategoryMap map[string]map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionTag, error) {
ofxDataReader, err := createNewOFXFileReader(ctx, data)
if err != nil {
@@ -44,5 +44,5 @@ func (c *ofxTransactionDataImporter) ParseImportedData(ctx core.Context, user *m
dataTableImporter := converter.CreateNewSimpleImporterWithTypeNameMapping(ofxTransactionTypeNameMapping)
return dataTableImporter.ParseImportedData(ctx, user, transactionDataTable, defaultTimezoneOffset, accountMap, expenseCategoryMap, incomeCategoryMap, transferCategoryMap, tagMap)
return dataTableImporter.ParseImportedData(ctx, user, transactionDataTable, defaultTimezoneOffset, additionalOptions, accountMap, expenseCategoryMap, incomeCategoryMap, transferCategoryMap, tagMap)
}

View File

@@ -5,6 +5,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/mayswind/ezbookkeeping/pkg/converters/converter"
"github.com/mayswind/ezbookkeeping/pkg/core"
"github.com/mayswind/ezbookkeeping/pkg/errs"
"github.com/mayswind/ezbookkeeping/pkg/models"
@@ -12,7 +13,7 @@ import (
)
func TestOFXTransactionDataFileParseImportedData_MinimumValidData(t *testing.T) {
converter := OFXTransactionDataImporter
importer := OFXTransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -20,7 +21,7 @@ func TestOFXTransactionDataFileParseImportedData_MinimumValidData(t *testing.T)
DefaultCurrency: "CNY",
}
allNewTransactions, allNewAccounts, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, allNewTags, err := converter.ParseImportedData(context, user, []byte(
allNewTransactions, allNewAccounts, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, allNewTags, err := importer.ParseImportedData(context, user, []byte(
"<OFX>\n"+
" <BANKMSGSRSV1>\n"+
" <STMTTRNRS>\n"+
@@ -76,7 +77,7 @@ func TestOFXTransactionDataFileParseImportedData_MinimumValidData(t *testing.T)
" </CCSTMTRS>\n"+
" </CCSTMTTRNRS>\n"+
" </CREDITCARDMSGSRSV1>\n"+
"</OFX>"), 0, nil, nil, nil, nil, nil)
"</OFX>"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
@@ -160,7 +161,7 @@ func TestOFXTransactionDataFileParseImportedData_MinimumValidData(t *testing.T)
}
func TestOFXTransactionDataFileParseImportedData_ParseAccountTo(t *testing.T) {
converter := OFXTransactionDataImporter
importer := OFXTransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -168,7 +169,7 @@ func TestOFXTransactionDataFileParseImportedData_ParseAccountTo(t *testing.T) {
DefaultCurrency: "CNY",
}
allNewTransactions, allNewAccounts, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
allNewTransactions, allNewAccounts, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"<OFX>\n"+
" <BANKMSGSRSV1>\n"+
" <STMTTRNRS>\n"+
@@ -210,7 +211,7 @@ func TestOFXTransactionDataFileParseImportedData_ParseAccountTo(t *testing.T) {
" </CCSTMTRS>\n"+
" </CCSTMTTRNRS>\n"+
" </CREDITCARDMSGSRSV1>\n"+
"</OFX>"), 0, nil, nil, nil, nil, nil)
"</OFX>"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
@@ -243,7 +244,7 @@ func TestOFXTransactionDataFileParseImportedData_ParseAccountTo(t *testing.T) {
}
func TestOFXTransactionDataFileParseImportedData_ParseValidTransactionTime(t *testing.T) {
converter := OFXTransactionDataImporter
importer := OFXTransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -251,7 +252,7 @@ func TestOFXTransactionDataFileParseImportedData_ParseValidTransactionTime(t *te
DefaultCurrency: "CNY",
}
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"<OFX>\n"+
" <BANKMSGSRSV1>\n"+
" <STMTTRNRS>\n"+
@@ -295,7 +296,7 @@ func TestOFXTransactionDataFileParseImportedData_ParseValidTransactionTime(t *te
" </STMTRS>\n"+
" </STMTTRNRS>\n"+
" </BANKMSGSRSV1>\n"+
"</OFX>"), 0, nil, nil, nil, nil, nil)
"</OFX>"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
@@ -310,7 +311,7 @@ func TestOFXTransactionDataFileParseImportedData_ParseValidTransactionTime(t *te
}
func TestOFXTransactionDataFileParseImportedData_ParseInvalidTransactionTime(t *testing.T) {
converter := OFXTransactionDataImporter
importer := OFXTransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -318,7 +319,7 @@ func TestOFXTransactionDataFileParseImportedData_ParseInvalidTransactionTime(t *
DefaultCurrency: "CNY",
}
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"<OFX>\n"+
" <BANKMSGSRSV1>\n"+
" <STMTTRNRS>\n"+
@@ -337,10 +338,10 @@ func TestOFXTransactionDataFileParseImportedData_ParseInvalidTransactionTime(t *
" </STMTRS>\n"+
" </STMTTRNRS>\n"+
" </BANKMSGSRSV1>\n"+
"</OFX>"), 0, nil, nil, nil, nil, nil)
"</OFX>"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrTransactionTimeInvalid.Message)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"<OFX>\n"+
" <BANKMSGSRSV1>\n"+
" <STMTTRNRS>\n"+
@@ -359,10 +360,10 @@ func TestOFXTransactionDataFileParseImportedData_ParseInvalidTransactionTime(t *
" </STMTRS>\n"+
" </STMTTRNRS>\n"+
" </BANKMSGSRSV1>\n"+
"</OFX>"), 0, nil, nil, nil, nil, nil)
"</OFX>"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrTransactionTimeInvalid.Message)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"<OFX>\n"+
" <BANKMSGSRSV1>\n"+
" <STMTTRNRS>\n"+
@@ -381,10 +382,10 @@ func TestOFXTransactionDataFileParseImportedData_ParseInvalidTransactionTime(t *
" </STMTRS>\n"+
" </STMTTRNRS>\n"+
" </BANKMSGSRSV1>\n"+
"</OFX>"), 0, nil, nil, nil, nil, nil)
"</OFX>"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrTransactionTimeInvalid.Message)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"<OFX>\n"+
" <BANKMSGSRSV1>\n"+
" <STMTTRNRS>\n"+
@@ -403,12 +404,12 @@ func TestOFXTransactionDataFileParseImportedData_ParseInvalidTransactionTime(t *
" </STMTRS>\n"+
" </STMTTRNRS>\n"+
" </BANKMSGSRSV1>\n"+
"</OFX>"), 0, nil, nil, nil, nil, nil)
"</OFX>"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrTransactionTimeInvalid.Message)
}
func TestOFXTransactionDataFileParseImportedData_ParseAmount_CommaAsDecimalPoint(t *testing.T) {
converter := OFXTransactionDataImporter
importer := OFXTransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -416,7 +417,7 @@ func TestOFXTransactionDataFileParseImportedData_ParseAmount_CommaAsDecimalPoint
DefaultCurrency: "CNY",
}
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"<OFX>\n"+
" <BANKMSGSRSV1>\n"+
" <STMTTRNRS>\n"+
@@ -435,7 +436,7 @@ func TestOFXTransactionDataFileParseImportedData_ParseAmount_CommaAsDecimalPoint
" </STMTRS>\n"+
" </STMTTRNRS>\n"+
" </BANKMSGSRSV1>\n"+
"</OFX>"), 0, nil, nil, nil, nil, nil)
"</OFX>"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
@@ -444,7 +445,7 @@ func TestOFXTransactionDataFileParseImportedData_ParseAmount_CommaAsDecimalPoint
}
func TestOFXTransactionDataFileParseImportedData_ParseInvalidAmount(t *testing.T) {
converter := OFXTransactionDataImporter
importer := OFXTransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -452,7 +453,7 @@ func TestOFXTransactionDataFileParseImportedData_ParseInvalidAmount(t *testing.T
DefaultCurrency: "CNY",
}
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"<OFX>\n"+
" <BANKMSGSRSV1>\n"+
" <STMTTRNRS>\n"+
@@ -471,12 +472,12 @@ func TestOFXTransactionDataFileParseImportedData_ParseInvalidAmount(t *testing.T
" </STMTRS>\n"+
" </STMTTRNRS>\n"+
" </BANKMSGSRSV1>\n"+
"</OFX>"), 0, nil, nil, nil, nil, nil)
"</OFX>"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrAmountInvalid.Message)
}
func TestOFXTransactionDataFileParseImportedData_ParseTransactionCurrency(t *testing.T) {
converter := OFXTransactionDataImporter
importer := OFXTransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -484,7 +485,7 @@ func TestOFXTransactionDataFileParseImportedData_ParseTransactionCurrency(t *tes
DefaultCurrency: "CNY",
}
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"<OFX>\n"+
" <BANKMSGSRSV1>\n"+
" <STMTTRNRS>\n"+
@@ -504,7 +505,7 @@ func TestOFXTransactionDataFileParseImportedData_ParseTransactionCurrency(t *tes
" </STMTRS>\n"+
" </STMTTRNRS>\n"+
" </BANKMSGSRSV1>\n"+
"</OFX>"), 0, nil, nil, nil, nil, nil)
"</OFX>"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
@@ -512,7 +513,7 @@ func TestOFXTransactionDataFileParseImportedData_ParseTransactionCurrency(t *tes
}
func TestOFXTransactionDataFileParseImportedData_ParseDescription(t *testing.T) {
converter := OFXTransactionDataImporter
importer := OFXTransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -520,7 +521,7 @@ func TestOFXTransactionDataFileParseImportedData_ParseDescription(t *testing.T)
DefaultCurrency: "CNY",
}
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"<OFX>\n"+
" <BANKMSGSRSV1>\n"+
" <STMTTRNRS>\n"+
@@ -541,13 +542,13 @@ func TestOFXTransactionDataFileParseImportedData_ParseDescription(t *testing.T)
" </STMTRS>\n"+
" </STMTTRNRS>\n"+
" </BANKMSGSRSV1>\n"+
"</OFX>"), 0, nil, nil, nil, nil, nil)
"</OFX>"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
assert.Equal(t, "foo bar\t#test", allNewTransactions[0].Comment)
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"<OFX>\n"+
" <BANKMSGSRSV1>\n"+
" <STMTTRNRS>\n"+
@@ -567,13 +568,13 @@ func TestOFXTransactionDataFileParseImportedData_ParseDescription(t *testing.T)
" </STMTRS>\n"+
" </STMTTRNRS>\n"+
" </BANKMSGSRSV1>\n"+
"</OFX>"), 0, nil, nil, nil, nil, nil)
"</OFX>"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
assert.Equal(t, "Test", allNewTransactions[0].Comment)
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"<OFX>\n"+
" <BANKMSGSRSV1>\n"+
" <STMTTRNRS>\n"+
@@ -595,7 +596,7 @@ func TestOFXTransactionDataFileParseImportedData_ParseDescription(t *testing.T)
" </STMTRS>\n"+
" </STMTTRNRS>\n"+
" </BANKMSGSRSV1>\n"+
"</OFX>"), 0, nil, nil, nil, nil, nil)
"</OFX>"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
@@ -603,7 +604,7 @@ func TestOFXTransactionDataFileParseImportedData_ParseDescription(t *testing.T)
}
func TestOFXTransactionDataFileParseImportedData_MissingAccountFromNode(t *testing.T) {
converter := OFXTransactionDataImporter
importer := OFXTransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -612,7 +613,7 @@ func TestOFXTransactionDataFileParseImportedData_MissingAccountFromNode(t *testi
}
// Missing Posted Date Node
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"<OFX>\n"+
" <BANKMSGSRSV1>\n"+
" <STMTTRNRS>\n"+
@@ -628,12 +629,12 @@ func TestOFXTransactionDataFileParseImportedData_MissingAccountFromNode(t *testi
" </STMTRS>\n"+
" </STMTTRNRS>\n"+
" </BANKMSGSRSV1>\n"+
"</OFX>"), 0, nil, nil, nil, nil, nil)
"</OFX>"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrMissingAccountData.Message)
}
func TestOFXTransactionDataFileParseImportedData_MissingCurrencyNode(t *testing.T) {
converter := OFXTransactionDataImporter
importer := OFXTransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -642,7 +643,7 @@ func TestOFXTransactionDataFileParseImportedData_MissingCurrencyNode(t *testing.
}
// Missing Default Currency Node
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"<OFX>\n"+
" <BANKMSGSRSV1>\n"+
" <STMTTRNRS>\n"+
@@ -660,12 +661,12 @@ func TestOFXTransactionDataFileParseImportedData_MissingCurrencyNode(t *testing.
" </STMTRS>\n"+
" </STMTTRNRS>\n"+
" </BANKMSGSRSV1>\n"+
"</OFX>"), 0, nil, nil, nil, nil, nil)
"</OFX>"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrAccountCurrencyInvalid.Message)
}
func TestOFXTransactionDataFileParseImportedData_MissingTransactionRequiredNode(t *testing.T) {
converter := OFXTransactionDataImporter
importer := OFXTransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -674,7 +675,7 @@ func TestOFXTransactionDataFileParseImportedData_MissingTransactionRequiredNode(
}
// Missing Posted Date Node
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"<OFX>\n"+
" <BANKMSGSRSV1>\n"+
" <STMTTRNRS>\n"+
@@ -692,11 +693,11 @@ func TestOFXTransactionDataFileParseImportedData_MissingTransactionRequiredNode(
" </STMTRS>\n"+
" </STMTTRNRS>\n"+
" </BANKMSGSRSV1>\n"+
"</OFX>"), 0, nil, nil, nil, nil, nil)
"</OFX>"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrMissingTransactionTime.Message)
// Missing Transaction Type Node
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"<OFX>\n"+
" <BANKMSGSRSV1>\n"+
" <STMTTRNRS>\n"+
@@ -714,11 +715,11 @@ func TestOFXTransactionDataFileParseImportedData_MissingTransactionRequiredNode(
" </STMTRS>\n"+
" </STMTTRNRS>\n"+
" </BANKMSGSRSV1>\n"+
"</OFX>"), 0, nil, nil, nil, nil, nil)
"</OFX>"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrTransactionTypeInvalid.Message)
// Missing Amount Node
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"<OFX>\n"+
" <BANKMSGSRSV1>\n"+
" <STMTTRNRS>\n"+
@@ -736,6 +737,6 @@ func TestOFXTransactionDataFileParseImportedData_MissingTransactionRequiredNode(
" </STMTRS>\n"+
" </STMTTRNRS>\n"+
" </BANKMSGSRSV1>\n"+
"</OFX>"), 0, nil, nil, nil, nil, nil)
"</OFX>"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrAmountInvalid.Message)
}

View File

@@ -35,7 +35,7 @@ var (
)
// ParseImportedData returns the imported data by parsing the quicken interchange format (qif) transaction data
func (c *qifTransactionDataImporter) ParseImportedData(ctx core.Context, user *models.User, data []byte, defaultTimezoneOffset int16, accountMap map[string]*models.Account, expenseCategoryMap map[string]map[string]*models.TransactionCategory, incomeCategoryMap map[string]map[string]*models.TransactionCategory, transferCategoryMap map[string]map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionTag, error) {
func (c *qifTransactionDataImporter) ParseImportedData(ctx core.Context, user *models.User, data []byte, defaultTimezoneOffset int16, additionalOptions converter.TransactionDataImporterOptions, accountMap map[string]*models.Account, expenseCategoryMap map[string]map[string]*models.TransactionCategory, incomeCategoryMap map[string]map[string]*models.TransactionCategory, transferCategoryMap map[string]map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionTag, error) {
qifDataReader := createNewQifDataReader(data)
qifData, err := qifDataReader.read(ctx)
@@ -51,5 +51,5 @@ func (c *qifTransactionDataImporter) ParseImportedData(ctx core.Context, user *m
dataTableImporter := converter.CreateNewSimpleImporterWithTypeNameMapping(qifTransactionTypeNameMapping)
return dataTableImporter.ParseImportedData(ctx, user, transactionDataTable, defaultTimezoneOffset, accountMap, expenseCategoryMap, incomeCategoryMap, transferCategoryMap, tagMap)
return dataTableImporter.ParseImportedData(ctx, user, transactionDataTable, defaultTimezoneOffset, additionalOptions, accountMap, expenseCategoryMap, incomeCategoryMap, transferCategoryMap, tagMap)
}

View File

@@ -5,6 +5,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/mayswind/ezbookkeeping/pkg/converters/converter"
"github.com/mayswind/ezbookkeeping/pkg/core"
"github.com/mayswind/ezbookkeeping/pkg/errs"
"github.com/mayswind/ezbookkeeping/pkg/models"
@@ -12,7 +13,7 @@ import (
)
func TestQIFTransactionDataFileParseImportedData_MinimumValidData(t *testing.T) {
converter := QifYearMonthDayTransactionDataImporter
importer := QifYearMonthDayTransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -20,7 +21,7 @@ func TestQIFTransactionDataFileParseImportedData_MinimumValidData(t *testing.T)
DefaultCurrency: "CNY",
}
allNewTransactions, allNewAccounts, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, allNewTags, err := converter.ParseImportedData(context, user, []byte(
allNewTransactions, allNewAccounts, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, allNewTags, err := importer.ParseImportedData(context, user, []byte(
"!Type:Bank\n"+
"D2024-09-01\n"+
"T123.45\n"+
@@ -42,7 +43,7 @@ func TestQIFTransactionDataFileParseImportedData_MinimumValidData(t *testing.T)
"D2024-09-05\n"+
"T0.06\n"+
"L[Test Account2]\n"+
"^\n"), 0, nil, nil, nil, nil, nil)
"^\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
@@ -113,7 +114,7 @@ func TestQIFTransactionDataFileParseImportedData_MinimumValidData(t *testing.T)
}
func TestQIFTransactionDataFileParseImportedData_ParseYearMonthDayDateFormatTime(t *testing.T) {
converter := QifYearMonthDayTransactionDataImporter
importer := QifYearMonthDayTransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -121,7 +122,7 @@ func TestQIFTransactionDataFileParseImportedData_ParseYearMonthDayDateFormatTime
DefaultCurrency: "CNY",
}
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"!Type:Bank\n"+
"D2024-09-01\n"+
"T-123.45\n"+
@@ -137,7 +138,7 @@ func TestQIFTransactionDataFileParseImportedData_ParseYearMonthDayDateFormatTime
"^\n"+
"D2024'9.5\n"+
"T-123.45\n"+
"^\n"), 0, nil, nil, nil, nil, nil)
"^\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
@@ -151,7 +152,7 @@ func TestQIFTransactionDataFileParseImportedData_ParseYearMonthDayDateFormatTime
}
func TestQIFTransactionDataFileParseImportedData_ParseMonthDayYearDateFormatTime(t *testing.T) {
converter := QifMonthDayYearTransactionDataImporter
importer := QifMonthDayYearTransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -159,7 +160,7 @@ func TestQIFTransactionDataFileParseImportedData_ParseMonthDayYearDateFormatTime
DefaultCurrency: "CNY",
}
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"!Type:Bank\n"+
"D09-01-2024\n"+
"T-123.45\n"+
@@ -175,7 +176,7 @@ func TestQIFTransactionDataFileParseImportedData_ParseMonthDayYearDateFormatTime
"^\n"+
"D9.5'2024\n"+
"T-123.45\n"+
"^\n"), 0, nil, nil, nil, nil, nil)
"^\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
@@ -189,7 +190,7 @@ func TestQIFTransactionDataFileParseImportedData_ParseMonthDayYearDateFormatTime
}
func TestQIFTransactionDataFileParseImportedData_ParseDayYearMonthDateFormatTime(t *testing.T) {
converter := QifDayMonthYearTransactionDataImporter
importer := QifDayMonthYearTransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -197,7 +198,7 @@ func TestQIFTransactionDataFileParseImportedData_ParseDayYearMonthDateFormatTime
DefaultCurrency: "CNY",
}
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"!Type:Bank\n"+
"D01-09-2024\n"+
"T-123.45\n"+
@@ -213,7 +214,7 @@ func TestQIFTransactionDataFileParseImportedData_ParseDayYearMonthDateFormatTime
"^\n"+
"D5'9.2024\n"+
"T-123.45\n"+
"^\n"), 0, nil, nil, nil, nil, nil)
"^\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
@@ -227,7 +228,7 @@ func TestQIFTransactionDataFileParseImportedData_ParseDayYearMonthDateFormatTime
}
func TestQIFTransactionDataFileParseImportedData_ParseShortYearMonthDayDateFormatTime(t *testing.T) {
converter := QifYearMonthDayTransactionDataImporter
importer := QifYearMonthDayTransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -235,7 +236,7 @@ func TestQIFTransactionDataFileParseImportedData_ParseShortYearMonthDayDateForma
DefaultCurrency: "CNY",
}
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"!Type:Bank\n"+
"D24-09-01\n"+
"T-123.45\n"+
@@ -251,7 +252,7 @@ func TestQIFTransactionDataFileParseImportedData_ParseShortYearMonthDayDateForma
"^\n"+
"D24'9.5\n"+
"T-123.45\n"+
"^\n"), 0, nil, nil, nil, nil, nil)
"^\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
@@ -265,7 +266,7 @@ func TestQIFTransactionDataFileParseImportedData_ParseShortYearMonthDayDateForma
}
func TestQIFTransactionDataFileParseImportedData_ParseInvalidTime(t *testing.T) {
converter := QifYearMonthDayTransactionDataImporter
importer := QifYearMonthDayTransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -273,16 +274,16 @@ func TestQIFTransactionDataFileParseImportedData_ParseInvalidTime(t *testing.T)
DefaultCurrency: "CNY",
}
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"!Type:Bank\n"+
"D2024 09 01\n"+
"T-123.45\n"+
"^\n"), 0, nil, nil, nil, nil, nil)
"^\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrTransactionTimeInvalid.Message)
}
func TestQIFTransactionDataFileParseImportedData_ParseAmountWithThousandsSeparator(t *testing.T) {
converter := QifYearMonthDayTransactionDataImporter
importer := QifYearMonthDayTransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -290,11 +291,11 @@ func TestQIFTransactionDataFileParseImportedData_ParseAmountWithThousandsSeparat
DefaultCurrency: "CNY",
}
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"!Type:Bank\n"+
"D2024-09-01\n"+
"T-123,456.78\n"+
"^\n"), 0, nil, nil, nil, nil, nil)
"^\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
@@ -304,7 +305,7 @@ func TestQIFTransactionDataFileParseImportedData_ParseAmountWithThousandsSeparat
}
func TestQIFTransactionDataFileParseImportedData_ParseInvalidAmount(t *testing.T) {
converter := QifYearMonthDayTransactionDataImporter
importer := QifYearMonthDayTransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -312,16 +313,16 @@ func TestQIFTransactionDataFileParseImportedData_ParseInvalidAmount(t *testing.T
DefaultCurrency: "CNY",
}
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"!Type:Bank\n"+
"D2024-09-01\n"+
"T-123 45\n"+
"^\n"), 0, nil, nil, nil, nil, nil)
"^\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrAmountInvalid.Message)
}
func TestQIFTransactionDataFileParseImportedData_ParseAccountType(t *testing.T) {
converter := QifYearMonthDayTransactionDataImporter
importer := QifYearMonthDayTransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -329,11 +330,11 @@ func TestQIFTransactionDataFileParseImportedData_ParseAccountType(t *testing.T)
DefaultCurrency: "CNY",
}
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"!Type:Cash\n"+
"D2024-09-01\n"+
"T-123.45\n"+
"^\n"), 0, nil, nil, nil, nil, nil)
"^\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
@@ -342,11 +343,11 @@ func TestQIFTransactionDataFileParseImportedData_ParseAccountType(t *testing.T)
assert.Equal(t, int64(1725148800), utils.GetUnixTimeFromTransactionTime(allNewTransactions[0].TransactionTime))
assert.Equal(t, int64(12345), allNewTransactions[0].Amount)
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"!Type:CCard\n"+
"D2024-09-01\n"+
"T-123.45\n"+
"^\n"), 0, nil, nil, nil, nil, nil)
"^\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
@@ -355,11 +356,11 @@ func TestQIFTransactionDataFileParseImportedData_ParseAccountType(t *testing.T)
assert.Equal(t, int64(1725148800), utils.GetUnixTimeFromTransactionTime(allNewTransactions[0].TransactionTime))
assert.Equal(t, int64(12345), allNewTransactions[0].Amount)
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"!Type:Oth A\n"+
"D2024-09-01\n"+
"T-123.45\n"+
"^\n"), 0, nil, nil, nil, nil, nil)
"^\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
@@ -368,11 +369,11 @@ func TestQIFTransactionDataFileParseImportedData_ParseAccountType(t *testing.T)
assert.Equal(t, int64(1725148800), utils.GetUnixTimeFromTransactionTime(allNewTransactions[0].TransactionTime))
assert.Equal(t, int64(12345), allNewTransactions[0].Amount)
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"!Type:Oth L\n"+
"D2024-09-01\n"+
"T-123.45\n"+
"^\n"), 0, nil, nil, nil, nil, nil)
"^\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
@@ -383,7 +384,7 @@ func TestQIFTransactionDataFileParseImportedData_ParseAccountType(t *testing.T)
}
func TestQIFTransactionDataFileParseImportedData_ParseAccount(t *testing.T) {
converter := QifYearMonthDayTransactionDataImporter
importer := QifYearMonthDayTransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -391,14 +392,14 @@ func TestQIFTransactionDataFileParseImportedData_ParseAccount(t *testing.T) {
DefaultCurrency: "CNY",
}
allNewTransactions, allNewAccounts, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
allNewTransactions, allNewAccounts, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"!Account\n"+
"NTest Account\n"+
"^\n"+
"!Type:Bank\n"+
"D2024-09-01\n"+
"T-123.45\n"+
"^\n"), 0, nil, nil, nil, nil, nil)
"^\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
@@ -412,7 +413,7 @@ func TestQIFTransactionDataFileParseImportedData_ParseAccount(t *testing.T) {
}
func TestQIFTransactionDataFileParseImportedData_ParseAmountWithLeadingPlusSign(t *testing.T) {
converter := QifYearMonthDayTransactionDataImporter
importer := QifYearMonthDayTransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -420,11 +421,11 @@ func TestQIFTransactionDataFileParseImportedData_ParseAmountWithLeadingPlusSign(
DefaultCurrency: "CNY",
}
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"!Type:Bank\n"+
"D2024-09-01\n"+
"T+123.45\n"+
"^\n"), 0, nil, nil, nil, nil, nil)
"^\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
@@ -432,7 +433,7 @@ func TestQIFTransactionDataFileParseImportedData_ParseAmountWithLeadingPlusSign(
}
func TestQIFTransactionDataFileParseImportedData_ParseSubCategory(t *testing.T) {
converter := QifYearMonthDayTransactionDataImporter
importer := QifYearMonthDayTransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -440,12 +441,12 @@ func TestQIFTransactionDataFileParseImportedData_ParseSubCategory(t *testing.T)
DefaultCurrency: "CNY",
}
allNewTransactions, _, allNewSubExpenseCategories, _, _, _, err := converter.ParseImportedData(context, user, []byte(
allNewTransactions, _, allNewSubExpenseCategories, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"!Type:Bank\n"+
"D2024-09-01\n"+
"T-123.45\n"+
"LTest Category:Sub Category\n"+
"^\n"), 0, nil, nil, nil, nil, nil)
"^\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
@@ -458,7 +459,7 @@ func TestQIFTransactionDataFileParseImportedData_ParseSubCategory(t *testing.T)
}
func TestQIFTransactionDataFileParseImportedData_ParseDescription(t *testing.T) {
converter := QifYearMonthDayTransactionDataImporter
importer := QifYearMonthDayTransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -466,7 +467,7 @@ func TestQIFTransactionDataFileParseImportedData_ParseDescription(t *testing.T)
DefaultCurrency: "CNY",
}
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"!Type:Bank\n"+
"D2024-09-01\n"+
"T-123.45\n"+
@@ -476,7 +477,24 @@ func TestQIFTransactionDataFileParseImportedData_ParseDescription(t *testing.T)
"D2024-09-02\n"+
"T-234.56\n"+
"PTest2\n"+
"^\n"), 0, nil, nil, nil, nil, nil)
"^\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 2, len(allNewTransactions))
assert.Equal(t, "foo bar\t#test", allNewTransactions[0].Comment)
assert.Equal(t, "", allNewTransactions[1].Comment)
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"!Type:Bank\n"+
"D2024-09-01\n"+
"T-123.45\n"+
"PTest\n"+
"Mfoo bar\t#test\n"+
"^\n"+
"D2024-09-02\n"+
"T-234.56\n"+
"PTest2\n"+
"^\n"), 0, converter.DefaultImporterOptions.WithPayeeAsDescription(), nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 2, len(allNewTransactions))
@@ -484,8 +502,41 @@ func TestQIFTransactionDataFileParseImportedData_ParseDescription(t *testing.T)
assert.Equal(t, "Test2", allNewTransactions[1].Comment)
}
func TestQIFTransactionDataFileParseImportedData_WithAdditionalOptions(t *testing.T) {
importer := QifYearMonthDayTransactionDataImporter
context := core.NewNullContext()
user := &models.User{
Uid: 1234567890,
DefaultCurrency: "CNY",
}
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"!Type:Bank\n"+
"D2024-09-01\n"+
"T-123.45\n"+
"PTest2\n"+
"^\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
assert.Equal(t, 0, len(allNewTransactions[0].OriginalTagNames))
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"!Type:Bank\n"+
"D2024-09-01\n"+
"T-123.45\n"+
"PTest2\n"+
"^\n"), 0, converter.DefaultImporterOptions.WithPayeeAsTag(), nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
assert.Equal(t, 1, len(allNewTransactions[0].OriginalTagNames))
assert.Equal(t, "Test2", allNewTransactions[0].OriginalTagNames[0])
}
func TestQIFTransactionDataFileParseImportedData_MissingRequiredFields(t *testing.T) {
converter := QifYearMonthDayTransactionDataImporter
importer := QifYearMonthDayTransactionDataImporter
context := core.NewNullContext()
user := &models.User{
@@ -494,16 +545,16 @@ func TestQIFTransactionDataFileParseImportedData_MissingRequiredFields(t *testin
}
// Missing Time Field
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(
"!Type:Bank\n"+
"T-123.45\n"+
"^\n"), 0, nil, nil, nil, nil, nil)
"^\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrMissingTransactionTime.Message)
// Missing Amount Field
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(
"!Type:Bank\n"+
"D2024-09-01\n"+
"^\n"), 0, nil, nil, nil, nil, nil)
"^\n"), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrAmountInvalid.Message)
}

View File

@@ -22,6 +22,7 @@ var qifTransactionSupportedColumns = map[datatable.TransactionDataTableColumn]bo
datatable.TRANSACTION_DATA_TABLE_AMOUNT: true,
datatable.TRANSACTION_DATA_TABLE_RELATED_ACCOUNT_NAME: true,
datatable.TRANSACTION_DATA_TABLE_DESCRIPTION: true,
datatable.TRANSACTION_DATA_TABLE_PAYEE: true,
}
// qifDateFormatType represents the quicken interchange format (qif) date format type
@@ -184,8 +185,10 @@ func (t *qifTransactionDataRowIterator) parseTransaction(ctx core.Context, user
if qifTransaction.Memo != "" {
data[datatable.TRANSACTION_DATA_TABLE_DESCRIPTION] = qifTransaction.Memo
} else if qifTransaction.Payee != "" && qifTransaction.Payee != qifOpeningBalancePayeeText {
data[datatable.TRANSACTION_DATA_TABLE_DESCRIPTION] = qifTransaction.Payee
}
if qifTransaction.Payee != "" && qifTransaction.Payee != qifOpeningBalancePayeeText {
data[datatable.TRANSACTION_DATA_TABLE_PAYEE] = qifTransaction.Payee
}
return data, nil

View File

@@ -27,7 +27,7 @@ var (
)
// ParseImportedData returns the imported data by parsing the wechat pay transaction csv data
func (c *wechatPayTransactionDataCsvFileImporter) ParseImportedData(ctx core.Context, user *models.User, data []byte, defaultTimezoneOffset int16, accountMap map[string]*models.Account, expenseCategoryMap map[string]map[string]*models.TransactionCategory, incomeCategoryMap map[string]map[string]*models.TransactionCategory, transferCategoryMap map[string]map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionTag, error) {
func (c *wechatPayTransactionDataCsvFileImporter) ParseImportedData(ctx core.Context, user *models.User, data []byte, defaultTimezoneOffset int16, additionalOptions converter.TransactionDataImporterOptions, accountMap map[string]*models.Account, expenseCategoryMap map[string]map[string]*models.TransactionCategory, incomeCategoryMap map[string]map[string]*models.TransactionCategory, transferCategoryMap map[string]map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionTag, error) {
fallback := unicode.UTF8.NewDecoder()
reader := transform.NewReader(bytes.NewReader(data), unicode.BOMOverride(fallback))
@@ -58,5 +58,5 @@ func (c *wechatPayTransactionDataCsvFileImporter) ParseImportedData(ctx core.Con
transactionDataTable := datatable.CreateNewTransactionDataTableFromCommonDataTable(commonDataTable, wechatPayTransactionSupportedColumns, transactionRowParser)
dataTableImporter := converter.CreateNewSimpleImporterWithTypeNameMapping(wechatPayTransactionTypeNameMapping)
return dataTableImporter.ParseImportedData(ctx, user, transactionDataTable, defaultTimezoneOffset, accountMap, expenseCategoryMap, incomeCategoryMap, transferCategoryMap, tagMap)
return dataTableImporter.ParseImportedData(ctx, user, transactionDataTable, defaultTimezoneOffset, additionalOptions, accountMap, expenseCategoryMap, incomeCategoryMap, transferCategoryMap, tagMap)
}

View File

@@ -6,6 +6,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/mayswind/ezbookkeeping/pkg/converters/converter"
"github.com/mayswind/ezbookkeeping/pkg/core"
"github.com/mayswind/ezbookkeeping/pkg/errs"
"github.com/mayswind/ezbookkeeping/pkg/models"
@@ -13,7 +14,7 @@ import (
)
func TestWeChatPayCsvFileImporterParseImportedData_MinimumValidData(t *testing.T) {
converter := WeChatPayTransactionDataCsvFileImporter
importer := WeChatPayTransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -31,7 +32,7 @@ func TestWeChatPayCsvFileImporterParseImportedData_MinimumValidData(t *testing.T
"2024-09-01 12:34:56,商户消费,支出,¥123.45,支付成功\n" +
"2024-09-01 23:59:59,零钱充值,/,¥0.05,充值完成\n" +
"2024-09-02 23:59:59,零钱提现,/,¥0.03,提现已到账\n"
allNewTransactions, allNewAccounts, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, allNewTags, err := converter.ParseImportedData(context, user, []byte(data), 0, nil, nil, nil, nil, nil)
allNewTransactions, allNewAccounts, allNewSubExpenseCategories, allNewSubIncomeCategories, allNewSubTransferCategories, allNewTags, err := importer.ParseImportedData(context, user, []byte(data), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 4, len(allNewTransactions))
@@ -93,7 +94,7 @@ func TestWeChatPayCsvFileImporterParseImportedData_MinimumValidData(t *testing.T
}
func TestWeChatPayCsvFileImporterParseImportedData_ParseRefundTransaction(t *testing.T) {
converter := WeChatPayTransactionDataCsvFileImporter
importer := WeChatPayTransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -108,7 +109,7 @@ func TestWeChatPayCsvFileImporterParseImportedData_ParseRefundTransaction(t *tes
"----------------------微信支付账单明细列表--------------------,,,,\n" +
"交易时间,交易类型,收/支,金额(元),当前状态\n" +
"2024-09-01 01:23:45,xxx-退款,收入,¥0.12,已全额退款\n"
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(data1), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(data1), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, int64(1234567890), allNewTransactions[0].Uid)
@@ -120,7 +121,7 @@ func TestWeChatPayCsvFileImporterParseImportedData_ParseRefundTransaction(t *tes
}
func TestWeChatPayCsvFileImporterParseImportedData_ParseInvalidTime(t *testing.T) {
converter := WeChatPayTransactionDataCsvFileImporter
importer := WeChatPayTransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -135,7 +136,7 @@ func TestWeChatPayCsvFileImporterParseImportedData_ParseInvalidTime(t *testing.T
"----------------------微信支付账单明细列表--------------------,,,,\n" +
"交易时间,交易类型,收/支,金额(元),当前状态\n" +
"2024-09-01T01:23:45,二维码收款,收入,¥0.12,已收钱\n"
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(data1), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(data1), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrTransactionTimeInvalid.Message)
data2 := "微信支付账单明细,,,,\n" +
@@ -145,12 +146,12 @@ func TestWeChatPayCsvFileImporterParseImportedData_ParseInvalidTime(t *testing.T
"----------------------微信支付账单明细列表--------------------,,,,\n" +
"交易时间,交易类型,收/支,金额(元),当前状态\n" +
"09/01/2024 12:34:56,二维码收款,收入,¥0.12,已收钱\n"
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data2), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(data2), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrTransactionTimeInvalid.Message)
}
func TestWeChatPayCsvFileImporterParseImportedData_ParseInvalidType(t *testing.T) {
converter := WeChatPayTransactionDataCsvFileImporter
importer := WeChatPayTransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -165,12 +166,12 @@ func TestWeChatPayCsvFileImporterParseImportedData_ParseInvalidType(t *testing.T
"----------------------微信支付账单明细列表--------------------,,,,\n" +
"交易时间,交易类型,收/支,金额(元),当前状态\n" +
"2024-09-01T01:23:45,xxx,,¥0.12,支付成功\n"
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(data), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(data), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrNotFoundTransactionDataInFile.Message)
}
func TestWeChatPayCsvFileImporterParseImportedData_ParseInvalidAmount(t *testing.T) {
converter := WeChatPayTransactionDataCsvFileImporter
importer := WeChatPayTransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -185,12 +186,12 @@ func TestWeChatPayCsvFileImporterParseImportedData_ParseInvalidAmount(t *testing
"----------------------微信支付账单明细列表--------------------,,,,\n" +
"交易时间,交易类型,收/支,金额(元),当前状态\n" +
"2024-09-01 01:23:45,二维码收款,收入,¥,已收钱\n"
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(data), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(data), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrAmountInvalid.Message)
}
func TestWeChatPayCsvFileImporterParseImportedData_ParseAccountName(t *testing.T) {
converter := WeChatPayTransactionDataCsvFileImporter
importer := WeChatPayTransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -206,7 +207,7 @@ func TestWeChatPayCsvFileImporterParseImportedData_ParseAccountName(t *testing.T
"----------------------微信支付账单明细列表--------------------,,,,\n" +
"交易时间,交易类型,收/支,金额(元),支付方式,当前状态\n" +
"2024-09-01 01:23:45,二维码收款,收入,¥0.12,/,已收钱\n"
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(data1), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(data1), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
@@ -222,7 +223,7 @@ func TestWeChatPayCsvFileImporterParseImportedData_ParseAccountName(t *testing.T
"2024-09-01 01:23:45,xxx-退款,收入,¥0.12,test,已全额退款\n"
assert.Nil(t, err)
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data2), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(data2), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
@@ -238,7 +239,7 @@ func TestWeChatPayCsvFileImporterParseImportedData_ParseAccountName(t *testing.T
"2024-09-01 23:59:59,零钱充值,/,¥0.05,test,充值完成\n"
assert.Nil(t, err)
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data3), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(data3), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
@@ -255,7 +256,7 @@ func TestWeChatPayCsvFileImporterParseImportedData_ParseAccountName(t *testing.T
"2024-09-02 23:59:59,零钱提现,/,¥0.03,test,提现已到账\n"
assert.Nil(t, err)
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data4), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(data4), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
@@ -272,7 +273,7 @@ func TestWeChatPayCsvFileImporterParseImportedData_ParseAccountName(t *testing.T
"2024-09-03 23:59:59,信用卡还款,/,¥0.01,零钱,支付成功\n"
assert.Nil(t, err)
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data5), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(data5), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
@@ -281,7 +282,7 @@ func TestWeChatPayCsvFileImporterParseImportedData_ParseAccountName(t *testing.T
}
func TestWeChatPayCsvFileImporterParseImportedData_ParseDescription(t *testing.T) {
converter := WeChatPayTransactionDataCsvFileImporter
importer := WeChatPayTransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -296,7 +297,7 @@ func TestWeChatPayCsvFileImporterParseImportedData_ParseDescription(t *testing.T
"----------------------微信支付账单明细列表--------------------,,,,\n" +
"交易时间,交易类型,收/支,金额(元),当前状态,备注\n" +
"2024-09-01 01:23:45,二维码收款,收入,¥0.12,已收钱,\"/\"\n"
allNewTransactions, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(data1), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(data1), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Nil(t, err)
assert.Equal(t, 1, len(allNewTransactions))
@@ -309,7 +310,7 @@ func TestWeChatPayCsvFileImporterParseImportedData_ParseDescription(t *testing.T
"----------------------微信支付账单明细列表--------------------,,,,\n" +
"交易时间,交易类型,商品,收/支,金额(元),当前状态,备注\n" +
"2024-09-01 01:23:45,二维码收款,Test,收入,¥0.12,已收钱,\"foo\"\"bar,\ntest\"\n"
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data2), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(data2), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Equal(t, 1, len(allNewTransactions))
assert.Equal(t, "foo\"bar,\ntest", allNewTransactions[0].Comment)
@@ -320,13 +321,13 @@ func TestWeChatPayCsvFileImporterParseImportedData_ParseDescription(t *testing.T
"----------------------微信支付账单明细列表--------------------,,,,\n" +
"交易时间,交易类型,商品,收/支,金额(元),当前状态,备注\n" +
"2024-09-01 01:23:45,二维码收款,Test,收入,¥0.12,已收钱,\"\"\n"
allNewTransactions, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data3), 0, nil, nil, nil, nil, nil)
allNewTransactions, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(data3), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.Equal(t, 1, len(allNewTransactions))
assert.Equal(t, "Test", allNewTransactions[0].Comment)
}
func TestWeChatPayCsvFileImporterParseImportedData_SkipUnknownTransferTransaction(t *testing.T) {
converter := WeChatPayTransactionDataCsvFileImporter
importer := WeChatPayTransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -341,12 +342,12 @@ func TestWeChatPayCsvFileImporterParseImportedData_SkipUnknownTransferTransactio
"----------------------微信支付账单明细列表--------------------,,,,\n" +
"交易时间,交易类型,收/支,金额(元),当前状态\n" +
"2024-09-01 23:59:59,/,/,¥0.05,充值完成\n"
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(data), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(data), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrNotFoundTransactionDataInFile.Message)
}
func TestWeChatPayCsvFileImporterParseImportedData_MissingFileHeader(t *testing.T) {
converter := WeChatPayTransactionDataCsvFileImporter
importer := WeChatPayTransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -356,15 +357,15 @@ func TestWeChatPayCsvFileImporterParseImportedData_MissingFileHeader(t *testing.
data := "交易时间,交易类型,收/支,金额(元),当前状态\n" +
"2024-09-01 01:23:45,二维码收款,收入,¥0.12,已收钱\n"
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(data), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(data), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrInvalidFileHeader.Message)
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(""), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(""), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrInvalidFileHeader.Message)
}
func TestWeChatPayCsvFileImporterParseImportedData_MissingRequiredColumn(t *testing.T) {
converter := WeChatPayTransactionDataCsvFileImporter
importer := WeChatPayTransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -380,7 +381,7 @@ func TestWeChatPayCsvFileImporterParseImportedData_MissingRequiredColumn(t *test
"----------------------微信支付账单明细列表--------------------,,,,\n" +
"交易类型,收/支,金额(元),当前状态\n" +
"二维码收款,收入,¥0.12,已收钱\n"
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(data1), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(data1), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrMissingRequiredFieldInHeaderRow.Message)
// Missing Category Column
@@ -391,7 +392,7 @@ func TestWeChatPayCsvFileImporterParseImportedData_MissingRequiredColumn(t *test
"----------------------微信支付账单明细列表--------------------,,,,\n" +
"交易时间,收/支,金额(元),当前状态\n" +
"2024-09-01 01:23:45,收入,¥0.12,已收钱\n"
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data2), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(data2), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrMissingRequiredFieldInHeaderRow.Message)
// Missing Type Column
@@ -402,7 +403,7 @@ func TestWeChatPayCsvFileImporterParseImportedData_MissingRequiredColumn(t *test
"----------------------微信支付账单明细列表--------------------,,,,\n" +
"交易时间,交易类型,金额(元),当前状态\n" +
"2024-09-01 01:23:45,二维码收款,¥0.12,已收钱\n"
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data3), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(data3), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrMissingRequiredFieldInHeaderRow.Message)
// Missing Amount Column
@@ -413,7 +414,7 @@ func TestWeChatPayCsvFileImporterParseImportedData_MissingRequiredColumn(t *test
"----------------------微信支付账单明细列表--------------------,,,,\n" +
"交易时间,交易类型,收/支,当前状态\n" +
"2024-09-01 01:23:45,二维码收款,收入,已收钱\n"
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data4), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(data4), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrMissingRequiredFieldInHeaderRow.Message)
// Missing Status Column
@@ -424,12 +425,12 @@ func TestWeChatPayCsvFileImporterParseImportedData_MissingRequiredColumn(t *test
"----------------------微信支付账单明细列表--------------------,,,,\n" +
"交易时间,交易类型,收/支,金额(元)\n" +
"2024-09-01 01:23:45,二维码收款,收入,¥0.12\n"
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data5), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err = importer.ParseImportedData(context, user, []byte(data5), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrMissingRequiredFieldInHeaderRow.Message)
}
func TestWeChatPayCsvFileImporterParseImportedData_NoTransactionData(t *testing.T) {
converter := WeChatPayTransactionDataCsvFileImporter
importer := WeChatPayTransactionDataCsvFileImporter
context := core.NewNullContext()
user := &models.User{
@@ -443,6 +444,6 @@ func TestWeChatPayCsvFileImporterParseImportedData_NoTransactionData(t *testing.
",,,,\n" +
"----------------------微信支付账单明细列表--------------------,,,,\n" +
"交易时间,交易类型,收/支,金额(元),当前状态\n"
_, _, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(data), 0, nil, nil, nil, nil, nil)
_, _, _, _, _, _, err := importer.ParseImportedData(context, user, []byte(data), 0, converter.DefaultImporterOptions, nil, nil, nil, nil, nil)
assert.EqualError(t, err, errs.ErrNotFoundTransactionDataInFile.Message)
}

View File

@@ -21,7 +21,7 @@ var (
)
// ParseImportedData returns the imported data by parsing the wechat pay transaction csv data
func (c *wechatPayTransactionDataXlsxFileImporter) ParseImportedData(ctx core.Context, user *models.User, data []byte, defaultTimezoneOffset int16, accountMap map[string]*models.Account, expenseCategoryMap map[string]map[string]*models.TransactionCategory, incomeCategoryMap map[string]map[string]*models.TransactionCategory, transferCategoryMap map[string]map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionTag, error) {
func (c *wechatPayTransactionDataXlsxFileImporter) ParseImportedData(ctx core.Context, user *models.User, data []byte, defaultTimezoneOffset int16, additionalOptions converter.TransactionDataImporterOptions, accountMap map[string]*models.Account, expenseCategoryMap map[string]map[string]*models.TransactionCategory, incomeCategoryMap map[string]map[string]*models.TransactionCategory, transferCategoryMap map[string]map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionCategory, []*models.TransactionTag, error) {
xlsxDataTable, err := excel.CreateNewExcelOOXMLFileBasicDataTable(data, false)
if err != nil {
@@ -49,5 +49,5 @@ func (c *wechatPayTransactionDataXlsxFileImporter) ParseImportedData(ctx core.Co
transactionDataTable := datatable.CreateNewTransactionDataTableFromCommonDataTable(commonDataTable, wechatPayTransactionSupportedColumns, transactionRowParser)
dataTableImporter := converter.CreateNewSimpleImporterWithTypeNameMapping(wechatPayTransactionTypeNameMapping)
return dataTableImporter.ParseImportedData(ctx, user, transactionDataTable, defaultTimezoneOffset, accountMap, expenseCategoryMap, incomeCategoryMap, transferCategoryMap, tagMap)
return dataTableImporter.ParseImportedData(ctx, user, transactionDataTable, defaultTimezoneOffset, additionalOptions, accountMap, expenseCategoryMap, incomeCategoryMap, transferCategoryMap, tagMap)
}

View File

@@ -168,7 +168,11 @@ export const SUPPORTED_IMPORT_FILE_CATEGORY_AND_TYPES: ImportFileCategoryAndType
type: 'qif_dmy',
name: 'Day-month-year format',
}
]
],
supportedAdditionalOptions: {
payeeAsTag: false,
payeeAsDescription: true
}
},
{
type: 'iif',

View File

@@ -75,6 +75,11 @@ export interface NameNumeralValue {
readonly value: number;
}
export interface KeyAndName {
readonly key: string;
readonly name: string;
}
export interface TypeAndName {
readonly type: number;
readonly name: string;

View File

@@ -68,6 +68,14 @@ export interface ImportFileCategoryAndTypes {
readonly fileTypes: ImportFileType[];
}
export interface ImportFileTypeSupportedAdditionalOptions extends Record<string, boolean | undefined> {
readonly payeeAsTag?: boolean;
readonly payeeAsDescription?: boolean;
readonly memberAsTag?: boolean;
readonly projectAsTag?: boolean;
readonly merchantAsTag?: boolean;
}
export interface ImportFileType extends ImportFileTypeAndExtensions {
readonly type: string;
readonly name: string;
@@ -75,6 +83,7 @@ export interface ImportFileType extends ImportFileTypeAndExtensions {
readonly subTypes?: ImportFileTypeSubType[];
readonly supportedEncodings?: string[];
readonly dataFromTextbox?: boolean;
readonly supportedAdditionalOptions?: ImportFileTypeSupportedAdditionalOptions;
readonly document?: {
readonly supportMultiLanguages: boolean | string;
readonly anchor: string;
@@ -99,6 +108,7 @@ export interface LocalizedImportFileType extends ImportFileTypeAndExtensions {
readonly subTypes?: LocalizedImportFileTypeSubType[];
readonly supportedEncodings?: LocalizedImportFileTypeSupportedEncodings[];
readonly dataFromTextbox?: boolean;
readonly supportedAdditionalOptions?: ImportFileTypeSupportedAdditionalOptions;
readonly document?: LocalizedImportFileDocument;
}

View File

@@ -8,6 +8,9 @@ import type {
import type {
VersionInfo
} from '@/core/version.ts';
import type {
ImportFileTypeSupportedAdditionalOptions
} from '@/core/file.ts';
import {
TransactionType
} from '@/core/transaction.ts';
@@ -160,7 +163,8 @@ import {
import {
isDefined,
isBoolean
isBoolean,
objectFieldWithValueToArrayItem
} from './common.ts';
import {
getGoogleMapAPIKey,
@@ -588,11 +592,16 @@ export default {
timeout: DEFAULT_UPLOAD_API_TIMEOUT
} as ApiRequestConfig);
},
parseImportTransaction: ({ fileType, fileEncoding, importFile, columnMapping, transactionTypeMapping, hasHeaderLine, timeFormat, timezoneFormat, amountDecimalSeparator, amountDigitGroupingSymbol, geoSeparator, geoOrder, tagSeparator }: { fileType: string, fileEncoding?: string, importFile: File, columnMapping?: Record<number, number>, transactionTypeMapping?: Record<string, TransactionType>, hasHeaderLine?: boolean, timeFormat?: string, timezoneFormat?: string, amountDecimalSeparator?: string, amountDigitGroupingSymbol?: string, geoSeparator?: string, geoOrder?: string, tagSeparator?: string }): ApiResponsePromise<ImportTransactionResponsePageWrapper> => {
parseImportTransaction: ({ fileType, additionalOptions, fileEncoding, importFile, columnMapping, transactionTypeMapping, hasHeaderLine, timeFormat, timezoneFormat, amountDecimalSeparator, amountDigitGroupingSymbol, geoSeparator, geoOrder, tagSeparator }: { fileType: string, additionalOptions?: ImportFileTypeSupportedAdditionalOptions, fileEncoding?: string, importFile: File, columnMapping?: Record<number, number>, transactionTypeMapping?: Record<string, TransactionType>, hasHeaderLine?: boolean, timeFormat?: string, timezoneFormat?: string, amountDecimalSeparator?: string, amountDigitGroupingSymbol?: string, geoSeparator?: string, geoOrder?: string, tagSeparator?: string }): ApiResponsePromise<ImportTransactionResponsePageWrapper> => {
let textualAdditionalOptions: string | undefined = undefined;
let textualColumnMapping: string | undefined = undefined;
let textualTransactionTypeMapping: string | undefined = undefined;
let textualHasHeaderLine: string | undefined = undefined;
if (additionalOptions) {
textualAdditionalOptions = objectFieldWithValueToArrayItem(additionalOptions, true).join(',');
}
if (columnMapping) {
textualColumnMapping = JSON.stringify(columnMapping);
}
@@ -607,6 +616,7 @@ export default {
return axios.postForm<ApiResponse<ImportTransactionResponsePageWrapper>>('v1/transactions/parse_import.json', {
fileType: fileType,
options: textualAdditionalOptions,
fileEncoding: fileEncoding,
file: importFile,
columnMapping: textualColumnMapping,

View File

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

View File

@@ -1885,6 +1885,9 @@
"Custom Script": "Custom Script",
"Execute Custom Script": "Execute Custom Script",
"Execute Custom Script to Parse Data": "Execute Custom Script to Parse Data",
"Additional Options": "Additional Options",
"Parse Payee as Tag": "Parse Payee as Tag",
"Parse Payee as Description": "Parse Payee as Description",
"Data File": "Data File",
"Data to import": "Data to import",
"Please select a file to import": "Please select a file to import",

View File

@@ -1885,6 +1885,9 @@
"Custom Script": "Custom Script",
"Execute Custom Script": "Execute Custom Script",
"Execute Custom Script to Parse Data": "Execute Custom Script to Parse Data",
"Additional Options": "Additional Options",
"Parse Payee as Tag": "Parse Payee as Tag",
"Parse Payee as Description": "Parse Payee as Description",
"Data File": "Archivo de datos",
"Data to import": "Data to import",
"Please select a file to import": "Please select a file to import",

View File

@@ -1885,6 +1885,9 @@
"Custom Script": "Script personnalisé",
"Execute Custom Script": "Exécuter le script personnalisé",
"Execute Custom Script to Parse Data": "Exécuter le script personnalisé pour analyser les données",
"Additional Options": "Additional Options",
"Parse Payee as Tag": "Parse Payee as Tag",
"Parse Payee as Description": "Parse Payee as Description",
"Data File": "Fichier de données",
"Data to import": "Données à importer",
"Please select a file to import": "Veuillez sélectionner un fichier à importer",

View File

@@ -1525,6 +1525,7 @@ export function useI18n() {
subTypes: subTypes.length ? subTypes : undefined,
supportedEncodings: supportedEncodings.length ? supportedEncodings : undefined,
dataFromTextbox: fileType.dataFromTextbox,
supportedAdditionalOptions: fileType.supportedAdditionalOptions,
document: document
};

View File

@@ -1885,6 +1885,9 @@
"Custom Script": "Custom Script",
"Execute Custom Script": "Execute Custom Script",
"Execute Custom Script to Parse Data": "Execute Custom Script to Parse Data",
"Additional Options": "Additional Options",
"Parse Payee as Tag": "Parse Payee as Tag",
"Parse Payee as Description": "Parse Payee as Description",
"Data File": "File dati",
"Data to import": "Dati da importare",
"Please select a file to import": "Seleziona un file da importare",

View File

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

View File

@@ -1885,6 +1885,9 @@
"Custom Script": "사용자 정의 스크립트",
"Execute Custom Script": "사용자 정의 스크립트 실행",
"Execute Custom Script to Parse Data": "데이터 구문 분석을 위한 사용자 정의 스크립트 실행",
"Additional Options": "Additional Options",
"Parse Payee as Tag": "Parse Payee as Tag",
"Parse Payee as Description": "Parse Payee as Description",
"Data File": "데이터 파일",
"Data to import": "가져올 데이터",
"Please select a file to import": "가져올 파일을 선택하십시오",

View File

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

View File

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

View File

@@ -1885,6 +1885,9 @@
"Custom Script": "Custom Script",
"Execute Custom Script": "Execute Custom Script",
"Execute Custom Script to Parse Data": "Execute Custom Script to Parse Data",
"Additional Options": "Additional Options",
"Parse Payee as Tag": "Parse Payee as Tag",
"Parse Payee as Description": "Parse Payee as Description",
"Data File": "Файл данных",
"Data to import": "Data to import",
"Please select a file to import": "Please select a file to import",

View File

@@ -1885,6 +1885,9 @@
"Custom Script": "สคริปต์กำหนดเอง",
"Execute Custom Script": "เรียกใช้สคริปต์กำหนดเอง",
"Execute Custom Script to Parse Data": "เรียกใช้สคริปต์กำหนดเองเพื่อแยกข้อมูล",
"Additional Options": "Additional Options",
"Parse Payee as Tag": "Parse Payee as Tag",
"Parse Payee as Description": "Parse Payee as Description",
"Data File": "ไฟล์ข้อมูล",
"Data to import": "ข้อมูลที่จะนำเข้า",
"Please select a file to import": "กรุณาเลือกไฟล์เพื่อนำเข้า",

View File

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

View File

@@ -1885,6 +1885,9 @@
"Custom Script": "Custom Script",
"Execute Custom Script": "Execute Custom Script",
"Execute Custom Script to Parse Data": "Execute Custom Script to Parse Data",
"Additional Options": "Additional Options",
"Parse Payee as Tag": "Parse Payee as Tag",
"Parse Payee as Description": "Parse Payee as Description",
"Data File": "Tệp dữ liệu",
"Data to import": "Data to import",
"Please select a file to import": "Please select a file to import",

View File

@@ -1885,6 +1885,9 @@
"Custom Script": "自定义脚本",
"Execute Custom Script": "执行自定义脚本",
"Execute Custom Script to Parse Data": "执行自定义脚本解析数据",
"Additional Options": "附加选项",
"Parse Payee as Tag": "将收款人解析为标签",
"Parse Payee as Description": "将收款人解析为描述",
"Data File": "数据文件",
"Data to import": "要导入的数据",
"Please select a file to import": "请选择要导入的文件",

View File

@@ -1885,6 +1885,9 @@
"Custom Script": "自訂腳本",
"Execute Custom Script": "執行自訂腳本",
"Execute Custom Script to Parse Data": "執行自訂腳本來解析資料",
"Additional Options": "附加選項",
"Parse Payee as Tag": "將收款人解析為標籤",
"Parse Payee as Description": "將收款人解析為描述",
"Data File": "資料檔案",
"Data to import": "要匯入的資料",
"Please select a file to import": "請選擇要匯入的檔案",

View File

@@ -12,6 +12,7 @@ import { useExchangeRatesStore } from './exchangeRates.ts';
import { type BeforeResolveFunction, itemAndIndex, entries, keys } from '@/core/base.ts';
import { type TextualYearMonth, DateRange } from '@/core/datetime.ts';
import { CategoryType } from '@/core/category.ts';
import type { ImportFileTypeSupportedAdditionalOptions } from '@/core/file.ts';
import { TransactionType, TransactionTagFilterType } from '@/core/transaction.ts';
import { TRANSACTION_MIN_AMOUNT, TRANSACTION_MAX_AMOUNT } from '@/consts/transaction.ts';
import {
@@ -1264,9 +1265,9 @@ export const useTransactionsStore = defineStore('transactions', () => {
});
}
function parseImportTransaction({ fileType, fileEncoding, importFile, columnMapping, transactionTypeMapping, hasHeaderLine, timeFormat, timezoneFormat, amountDecimalSeparator, amountDigitGroupingSymbol, geoSeparator, geoOrder, tagSeparator }: { fileType: string, fileEncoding?: string, importFile: File, columnMapping?: Record<number, number>, transactionTypeMapping?: Record<string, TransactionType>, hasHeaderLine?: boolean, timeFormat?: string, timezoneFormat?: string, amountDecimalSeparator?: string, amountDigitGroupingSymbol?: string, geoSeparator?: string, geoOrder?: string, tagSeparator?: string }): Promise<ImportTransactionResponsePageWrapper> {
function parseImportTransaction({ fileType, additionalOptions, fileEncoding, importFile, columnMapping, transactionTypeMapping, hasHeaderLine, timeFormat, timezoneFormat, amountDecimalSeparator, amountDigitGroupingSymbol, geoSeparator, geoOrder, tagSeparator }: { fileType: string, additionalOptions?: ImportFileTypeSupportedAdditionalOptions, fileEncoding?: string, importFile: File, columnMapping?: Record<number, number>, transactionTypeMapping?: Record<string, TransactionType>, hasHeaderLine?: boolean, timeFormat?: string, timezoneFormat?: string, amountDecimalSeparator?: string, amountDigitGroupingSymbol?: string, geoSeparator?: string, geoOrder?: string, tagSeparator?: string }): Promise<ImportTransactionResponsePageWrapper> {
return new Promise((resolve, reject) => {
services.parseImportTransaction({ fileType, fileEncoding, importFile, columnMapping, transactionTypeMapping, hasHeaderLine, timeFormat, timezoneFormat, amountDecimalSeparator, amountDigitGroupingSymbol, geoSeparator, geoOrder, tagSeparator }).then(response => {
services.parseImportTransaction({ fileType, additionalOptions, fileEncoding, importFile, columnMapping, transactionTypeMapping, hasHeaderLine, timeFormat, timezoneFormat, amountDecimalSeparator, amountDigitGroupingSymbol, geoSeparator, geoOrder, tagSeparator }).then(response => {
const data = response.data;
if (!data || !data.success || !data.result) {

View File

@@ -145,6 +145,31 @@
/>
</v-col>
<v-col cols="12" md="12" v-if="supportedAdditionalOptions">
<v-select
:disabled="submitting"
:label="tt('Additional Options')"
:placeholder="tt('Additional Options')"
v-model="fileType"
v-model:menu="additionalOptionsMenuState"
>
<template #selection>
<span class="cursor-pointer">{{ displaySelectedAdditionalOptions }}</span>
</template>
<template #no-data>
<v-list class="py-0">
<template v-for="item in allSupportedAdditionalOptions">
<v-list-item :key="item.key"
:append-icon="importAdditionalOptions[item.key] ? mdiCheck : undefined"
@click="importAdditionalOptions[item.key] = !importAdditionalOptions[item.key]"
v-if="isDefined(supportedAdditionalOptions[item.key])">{{ tt(item.name) }}</v-list-item>
</template>
</v-list>
</template>
</v-select>
</v-col>
<v-col cols="12" md="12" v-if="!isImportDataFromTextbox">
<v-text-field
readonly
@@ -257,15 +282,20 @@ import { useTransactionsStore } from '@/stores/transaction.ts';
import { useOverviewStore } from '@/stores/overview.ts';
import { useStatisticsStore } from '@/stores/statistics.ts';
import { itemAndIndex } from '@/core/base.ts';
import { type KeyAndName, itemAndIndex } from '@/core/base.ts';
import { type NumeralSystem } from '@/core/numeral.ts';
import { TransactionType } from '@/core/transaction.ts';
import { KnownFileType } from '@/core/file.ts';
import type { LocalizedImportFileCategoryAndTypes, LocalizedImportFileType, LocalizedImportFileTypeSubType, LocalizedImportFileTypeSupportedEncodings } from '@/core/file.ts';
import {
type ImportFileTypeSupportedAdditionalOptions,
type LocalizedImportFileCategoryAndTypes,
type LocalizedImportFileType,
type LocalizedImportFileTypeSubType,
type LocalizedImportFileTypeSupportedEncodings,
KnownFileType
} from '@/core/file.ts';
import { ImportTransaction } from '@/models/imported_transaction.ts';
import { isNumber } from '@/lib/common.ts';
import { isDefined, isNumber } from '@/lib/common.ts';
import { findExtensionByType, isFileExtensionSupported } from '@/lib/file.ts';
import { generateRandomUUID } from '@/lib/misc.ts';
import logger from '@/lib/logger.ts';
@@ -297,6 +327,7 @@ defineProps<{
const {
tt,
joinMultiText,
getCurrentNumeralSystemType,
getAllSupportedImportFileCagtegoryAndTypes,
formatNumberToLocalizedNumerals
@@ -316,7 +347,19 @@ const importTransactionExecuteCustomScriptTab = useTemplateRef<ImportTransaction
const importTransactionCheckDataTab = useTemplateRef<ImportTransactionCheckDataTabType>('importTransactionCheckDataTab');
const fileInput = useTemplateRef<HTMLInputElement>('fileInput');
const allSupportedAdditionalOptions: KeyAndName[] = [
{
key: 'payeeAsTag',
name: 'Parse Payee as Tag'
},
{
key: 'payeeAsDescription',
name: 'Parse Payee as Description'
}
];
const showState = ref<boolean>(false);
const additionalOptionsMenuState = ref<boolean>(false);
const clientSessionId = ref<string>('');
const currentStep = ref<ImportTransactionDialogStep>('uploadFile');
const importProcess = ref<number>(0);
@@ -326,6 +369,7 @@ const fileEncoding = ref<string>('utf-8');
const processDSVMethod = ref<ImportDSVProcessMethod>(ImportDSVProcessMethod.ColumnMapping);
const importFile = ref<File | null>(null);
const importData = ref<string>('');
const importAdditionalOptions = ref<ImportFileTypeSupportedAdditionalOptions>({});
const parsedFileData = ref<string[][] | undefined>(undefined);
const importTransactions = ref<ImportTransaction[] | undefined>(undefined);
@@ -342,6 +386,7 @@ const allSupportedImportFileCategoryAndTypes = computed<LocalizedImportFileCateg
const allFileSubTypes = computed<LocalizedImportFileTypeSubType[] | undefined>(() => allSupportedImportFileTypesMap.value[fileType.value]?.subTypes);
const allSupportedEncodings = computed<LocalizedImportFileTypeSupportedEncodings[] | undefined>(() => allSupportedImportFileTypesMap.value[fileType.value]?.supportedEncodings);
const isImportDataFromTextbox = computed<boolean>(() => allSupportedImportFileTypesMap.value[fileType.value]?.dataFromTextbox ?? false);
const supportedAdditionalOptions = computed<ImportFileTypeSupportedAdditionalOptions | undefined>(() => allSupportedImportFileTypesMap.value[fileType.value]?.supportedAdditionalOptions);
const allSteps = computed<StepBarItem[]>(() => {
const steps: StepBarItem[] = [
@@ -408,6 +453,26 @@ const supportedImportFileExtensions = computed<string | undefined>(() => {
return allSupportedImportFileTypesMap.value[fileType.value]?.extensions;
});
const displaySelectedAdditionalOptions = computed<string>(() => {
if (!supportedAdditionalOptions.value) {
return tt('None');
}
const selectedOptions: string[] = [];
for (const option of allSupportedAdditionalOptions) {
if (isDefined(supportedAdditionalOptions.value[option.key]) && importAdditionalOptions.value[option.key]) {
selectedOptions.push(tt(option.name));
}
}
if (selectedOptions.length < 1) {
return tt('None');
}
return joinMultiText(selectedOptions);
});
const exportFileGuideDocumentUrl = computed<string | undefined>(() => {
const document = allSupportedImportFileTypesMap.value[fileType.value]?.document;
@@ -437,6 +502,7 @@ function open(): Promise<void> {
importProcess.value = 0;
importFile.value = null;
importData.value = '';
importAdditionalOptions.value = Object.assign({}, supportedAdditionalOptions.value ?? {});
parsedFileData.value = undefined;
importTransactionDefineColumnTab.value?.reset();
importTransactionExecuteCustomScriptTab.value?.reset();
@@ -614,6 +680,7 @@ function parseData(): void {
transactionsStore.parseImportTransaction({
fileType: type,
additionalOptions: importAdditionalOptions.value,
fileEncoding: encoding,
importFile: uploadFile,
columnMapping: columnMapping,
@@ -773,6 +840,7 @@ watch(fileType, () => {
importFile.value = null;
parsedFileData.value = undefined;
importAdditionalOptions.value = Object.assign({}, supportedAdditionalOptions.value ?? {});
importTransactions.value = undefined;
});