code refactor

This commit is contained in:
MaysWind
2024-09-19 00:03:07 +08:00
parent fceb92eb6f
commit 7ecec2bb64
20 changed files with 283 additions and 277 deletions
@@ -1,4 +1,4 @@
package converters package base
import ( import (
"github.com/mayswind/ezbookkeeping/pkg/core" "github.com/mayswind/ezbookkeeping/pkg/core"
@@ -1,4 +1,4 @@
package converters package datatable
import "time" import "time"
@@ -1,4 +1,4 @@
package converters package datatable
import ( import (
"fmt" "fmt"
@@ -55,7 +55,36 @@ type DataTableTransactionDataImporter struct {
// DataTableTransactionDataImporterPostProcessFunc represents item post process function of DataTableTransactionDataImporter // DataTableTransactionDataImporterPostProcessFunc represents item post process function of DataTableTransactionDataImporter
type DataTableTransactionDataImporterPostProcessFunc func(core.Context, *models.ImportTransaction) error type DataTableTransactionDataImporterPostProcessFunc func(core.Context, *models.ImportTransaction) error
func (c *DataTableTransactionDataExporter) buildExportedContent(ctx core.Context, dataTableBuilder DataTableBuilder, uid int64, transactions []*models.Transaction, accountMap map[int64]*models.Account, categoryMap map[int64]*models.TransactionCategory, tagMap map[int64]*models.TransactionTag, allTagIndexes map[int64][]int64) error { // CreateNewDataTableTransactionDataExporter returns a new data table transaction data exporter according to the specified arguments
func CreateNewDataTableTransactionDataExporter(dataColumnMapping map[DataTableColumn]string, transactionTypeMapping map[models.TransactionType]string, geoLocationSeparator string, transactionTagSeparator string) *DataTableTransactionDataExporter {
return &DataTableTransactionDataExporter{
dataColumnMapping: dataColumnMapping,
transactionTypeMapping: transactionTypeMapping,
geoLocationSeparator: geoLocationSeparator,
transactionTagSeparator: transactionTagSeparator,
}
}
// CreateNewDataTableTransactionDataImporter returns a new data table transaction data importer according to the specified arguments
func CreateNewDataTableTransactionDataImporter(dataColumnMapping map[DataTableColumn]string, transactionTypeMapping map[models.TransactionType]string, geoLocationSeparator string, transactionTagSeparator string) *DataTableTransactionDataImporter {
return &DataTableTransactionDataImporter{
dataColumnMapping: dataColumnMapping,
transactionTypeMapping: transactionTypeMapping,
geoLocationSeparator: geoLocationSeparator,
transactionTagSeparator: transactionTagSeparator,
}
}
// CreateNewSimpleDataTableTransactionDataImporterWithPostProcessFunc returns a new data table transaction data importer according to the specified arguments
func CreateNewSimpleDataTableTransactionDataImporterWithPostProcessFunc(dataColumnMapping map[DataTableColumn]string, transactionTypeMapping map[models.TransactionType]string, postProcessFunc DataTableTransactionDataImporterPostProcessFunc) *DataTableTransactionDataImporter {
return &DataTableTransactionDataImporter{
dataColumnMapping: dataColumnMapping,
transactionTypeMapping: transactionTypeMapping,
postProcessFunc: postProcessFunc,
}
}
func (c *DataTableTransactionDataExporter) BuildExportedContent(ctx core.Context, dataTableBuilder DataTableBuilder, uid int64, transactions []*models.Transaction, accountMap map[int64]*models.Account, categoryMap map[int64]*models.TransactionCategory, tagMap map[int64]*models.TransactionTag, allTagIndexes map[int64][]int64) error {
for i := 0; i < len(transactions); i++ { for i := 0; i < len(transactions); i++ {
transaction := transactions[i] transaction := transactions[i]
@@ -192,7 +221,7 @@ func (c *DataTableTransactionDataExporter) getExportedTags(dataTableBuilder Data
return dataTableBuilder.ReplaceDelimiters(ret.String()) return dataTableBuilder.ReplaceDelimiters(ret.String())
} }
func (c *DataTableTransactionDataImporter) parseImportedData(ctx core.Context, user *models.User, dataTable ImportedDataTable, defaultTimezoneOffset int16, accountMap map[string]*models.Account, categoryMap map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionTag, error) { func (c *DataTableTransactionDataImporter) ParseImportedData(ctx core.Context, user *models.User, dataTable ImportedDataTable, defaultTimezoneOffset int16, accountMap map[string]*models.Account, categoryMap map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionTag, error) {
if dataTable.DataRowCount() < 1 { if dataTable.DataRowCount() < 1 {
log.Errorf(ctx, "[data_table_transaction_data_converter.parseImportedData] cannot parse import data for user \"uid:%d\", because data table row count is less 1", user.Uid) log.Errorf(ctx, "[data_table_transaction_data_converter.parseImportedData] cannot parse import data for user \"uid:%d\", because data table row count is less 1", user.Uid)
return nil, nil, nil, nil, errs.ErrNotFoundTransactionDataInFile return nil, nil, nil, nil, errs.ErrNotFoundTransactionDataInFile
@@ -1,4 +1,4 @@
package converters package datatable
import ( import (
"time" "time"
@@ -136,9 +136,10 @@ func (t *WritableDataRowIterator) Next() ImportedDataRow {
} }
} }
func createNewWritableDataTable(columns []DataTableColumn) (*WritableDataTable, error) { // CreateNewWritableDataTable returns a new writable data table according to the specified columns
func CreateNewWritableDataTable(columns []DataTableColumn) *WritableDataTable {
return &WritableDataTable{ return &WritableDataTable{
allData: make([]map[DataTableColumn]string, 0), allData: make([]map[DataTableColumn]string, 0),
columns: columns, columns: columns,
}, nil }
} }
@@ -1,4 +1,4 @@
package converters package datatable
import ( import (
"testing" "testing"
@@ -17,8 +17,7 @@ func TestWritableDataTableAdd(t *testing.T) {
columns[3] = DATA_TABLE_ACCOUNT_NAME columns[3] = DATA_TABLE_ACCOUNT_NAME
columns[4] = DATA_TABLE_AMOUNT columns[4] = DATA_TABLE_AMOUNT
writableDataTable, err := createNewWritableDataTable(columns) writableDataTable := CreateNewWritableDataTable(columns)
assert.Nil(t, err)
assert.Equal(t, 0, writableDataTable.DataRowCount()) assert.Equal(t, 0, writableDataTable.DataRowCount())
@@ -66,8 +65,7 @@ func TestWritableDataTableAdd_NotExistsColumn(t *testing.T) {
columns := make([]DataTableColumn, 1) columns := make([]DataTableColumn, 1)
columns[0] = DATA_TABLE_TRANSACTION_TIME columns[0] = DATA_TABLE_TRANSACTION_TIME
writableDataTable, err := createNewWritableDataTable(columns) writableDataTable := CreateNewWritableDataTable(columns)
assert.Nil(t, err)
expectedTransactionUnixTime := time.Now().Unix() expectedTransactionUnixTime := time.Now().Unix()
expectedTextualTransactionTime := utils.FormatUnixTimeToLongDateTime(expectedTransactionUnixTime, time.Local) expectedTextualTransactionTime := utils.FormatUnixTimeToLongDateTime(expectedTransactionUnixTime, time.Local)
@@ -87,9 +85,7 @@ func TestWritableDataTableGet_NotExistsRow(t *testing.T) {
columns := make([]DataTableColumn, 1) columns := make([]DataTableColumn, 1)
columns[0] = DATA_TABLE_TRANSACTION_TIME columns[0] = DATA_TABLE_TRANSACTION_TIME
writableDataTable, err := createNewWritableDataTable(columns) writableDataTable := CreateNewWritableDataTable(columns)
assert.Nil(t, err)
assert.Equal(t, 0, writableDataTable.DataRowCount()) assert.Equal(t, 0, writableDataTable.DataRowCount())
dataRow := writableDataTable.Get(0) dataRow := writableDataTable.Get(0)
@@ -100,8 +96,7 @@ func TestWritableDataRowGetData_NotExistsColumn(t *testing.T) {
columns := make([]DataTableColumn, 1) columns := make([]DataTableColumn, 1)
columns[0] = DATA_TABLE_TRANSACTION_TIME columns[0] = DATA_TABLE_TRANSACTION_TIME
writableDataTable, err := createNewWritableDataTable(columns) writableDataTable := CreateNewWritableDataTable(columns)
assert.Nil(t, err)
expectedTransactionUnixTime := time.Now().Unix() expectedTransactionUnixTime := time.Now().Unix()
expectedTextualTransactionTime := utils.FormatUnixTimeToLongDateTime(expectedTransactionUnixTime, time.Local) expectedTextualTransactionTime := utils.FormatUnixTimeToLongDateTime(expectedTransactionUnixTime, time.Local)
@@ -124,9 +119,7 @@ func TestWritableDataTableDataRowIterator(t *testing.T) {
columns[3] = DATA_TABLE_ACCOUNT_NAME columns[3] = DATA_TABLE_ACCOUNT_NAME
columns[4] = DATA_TABLE_AMOUNT columns[4] = DATA_TABLE_AMOUNT
writableDataTable, err := createNewWritableDataTable(columns) writableDataTable := CreateNewWritableDataTable(columns)
assert.Nil(t, err)
assert.Equal(t, 0, writableDataTable.DataRowCount()) assert.Equal(t, 0, writableDataTable.DataRowCount())
expectedTransactionUnixTimes := make([]int64, 3) expectedTransactionUnixTimes := make([]int64, 3)
@@ -0,0 +1,15 @@
package _default
// ezBookKeepingTransactionDataCSVFileConverter defines the structure of CSV file converter
type ezBookKeepingTransactionDataCSVFileConverter struct {
ezBookKeepingTransactionDataPlainTextConverter
}
// Initialize an ezbookkeeping transaction data csv file converter singleton instance
var (
EzBookKeepingTransactionDataCSVFileConverter = &ezBookKeepingTransactionDataCSVFileConverter{
ezBookKeepingTransactionDataPlainTextConverter{
columnSeparator: ",",
},
}
)
@@ -0,0 +1,105 @@
package _default
import (
"github.com/mayswind/ezbookkeeping/pkg/converters/datatable"
"github.com/mayswind/ezbookkeeping/pkg/core"
"github.com/mayswind/ezbookkeeping/pkg/models"
)
// ezBookKeepingTransactionDataPlainTextConverter defines the structure of ezbookkeeping plain text converter for transaction data
type ezBookKeepingTransactionDataPlainTextConverter struct {
columnSeparator string
}
const ezbookkeepingLineSeparator = "\n"
const ezbookkeepingGeoLocationSeparator = " "
const ezbookkeepingTagSeparator = ";"
var ezbookkeepingDataColumnNameMapping = map[datatable.DataTableColumn]string{
datatable.DATA_TABLE_TRANSACTION_TIME: "Time",
datatable.DATA_TABLE_TRANSACTION_TIMEZONE: "Timezone",
datatable.DATA_TABLE_TRANSACTION_TYPE: "Type",
datatable.DATA_TABLE_CATEGORY: "Category",
datatable.DATA_TABLE_SUB_CATEGORY: "Sub Category",
datatable.DATA_TABLE_ACCOUNT_NAME: "Account",
datatable.DATA_TABLE_ACCOUNT_CURRENCY: "Account Currency",
datatable.DATA_TABLE_AMOUNT: "Amount",
datatable.DATA_TABLE_RELATED_ACCOUNT_NAME: "Account2",
datatable.DATA_TABLE_RELATED_ACCOUNT_CURRENCY: "Account2 Currency",
datatable.DATA_TABLE_RELATED_AMOUNT: "Account2 Amount",
datatable.DATA_TABLE_GEOGRAPHIC_LOCATION: "Geographic Location",
datatable.DATA_TABLE_TAGS: "Tags",
datatable.DATA_TABLE_DESCRIPTION: "Description",
}
var ezbookkeepingTransactionTypeNameMapping = map[models.TransactionType]string{
models.TRANSACTION_TYPE_MODIFY_BALANCE: "Balance Modification",
models.TRANSACTION_TYPE_INCOME: "Income",
models.TRANSACTION_TYPE_EXPENSE: "Expense",
models.TRANSACTION_TYPE_TRANSFER: "Transfer",
}
var ezbookkeepingDataColumns = []datatable.DataTableColumn{
datatable.DATA_TABLE_TRANSACTION_TIME,
datatable.DATA_TABLE_TRANSACTION_TIMEZONE,
datatable.DATA_TABLE_TRANSACTION_TYPE,
datatable.DATA_TABLE_CATEGORY,
datatable.DATA_TABLE_SUB_CATEGORY,
datatable.DATA_TABLE_ACCOUNT_NAME,
datatable.DATA_TABLE_ACCOUNT_CURRENCY,
datatable.DATA_TABLE_AMOUNT,
datatable.DATA_TABLE_RELATED_ACCOUNT_NAME,
datatable.DATA_TABLE_RELATED_ACCOUNT_CURRENCY,
datatable.DATA_TABLE_RELATED_AMOUNT,
datatable.DATA_TABLE_GEOGRAPHIC_LOCATION,
datatable.DATA_TABLE_TAGS,
datatable.DATA_TABLE_DESCRIPTION,
}
// ToExportedContent returns the exported transaction plain text data
func (c *ezBookKeepingTransactionDataPlainTextConverter) ToExportedContent(ctx core.Context, uid int64, transactions []*models.Transaction, accountMap map[int64]*models.Account, categoryMap map[int64]*models.TransactionCategory, tagMap map[int64]*models.TransactionTag, allTagIndexes map[int64][]int64) ([]byte, error) {
dataTableBuilder := createNewezbookkeepingTransactionPlainTextDataTableBuilder(
len(transactions),
ezbookkeepingDataColumns,
ezbookkeepingDataColumnNameMapping,
c.columnSeparator,
ezbookkeepingLineSeparator,
)
dataTableExporter := datatable.CreateNewDataTableTransactionDataExporter(
ezbookkeepingDataColumnNameMapping,
ezbookkeepingTransactionTypeNameMapping,
ezbookkeepingGeoLocationSeparator,
ezbookkeepingTagSeparator,
)
err := dataTableExporter.BuildExportedContent(ctx, dataTableBuilder, uid, transactions, accountMap, categoryMap, tagMap, allTagIndexes)
if err != nil {
return nil, err
}
return []byte(dataTableBuilder.String()), nil
}
// ParseImportedData returns the imported data by parsing the transaction plain text data
func (c *ezBookKeepingTransactionDataPlainTextConverter) ParseImportedData(ctx core.Context, user *models.User, data []byte, defaultTimezoneOffset int16, accountMap map[string]*models.Account, categoryMap map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionTag, error) {
dataTable, err := createNewezbookkeepingTransactionPlainTextDataTable(
string(data),
c.columnSeparator,
ezbookkeepingLineSeparator,
)
if err != nil {
return nil, nil, nil, nil, err
}
dataTableImporter := datatable.CreateNewDataTableTransactionDataImporter(
ezbookkeepingDataColumnNameMapping,
ezbookkeepingTransactionTypeNameMapping,
ezbookkeepingGeoLocationSeparator,
ezbookkeepingTagSeparator,
)
return dataTableImporter.ParseImportedData(ctx, user, dataTable, defaultTimezoneOffset, accountMap, categoryMap, tagMap)
}
@@ -1,4 +1,4 @@
package converters package _default
import ( import (
"testing" "testing"
@@ -1,10 +1,11 @@
package converters package _default
import ( import (
"fmt" "fmt"
"strings" "strings"
"time" "time"
"github.com/mayswind/ezbookkeeping/pkg/converters/datatable"
"github.com/mayswind/ezbookkeeping/pkg/errs" "github.com/mayswind/ezbookkeeping/pkg/errs"
"github.com/mayswind/ezbookkeeping/pkg/utils" "github.com/mayswind/ezbookkeeping/pkg/utils"
) )
@@ -32,8 +33,8 @@ type ezBookKeepingTransactionPlainTextDataRowIterator struct {
type ezBookKeepingTransactionPlainTextDataTableBuilder struct { type ezBookKeepingTransactionPlainTextDataTableBuilder struct {
columnSeparator string columnSeparator string
lineSeparator string lineSeparator string
columns []DataTableColumn columns []datatable.DataTableColumn
dataColumnNameMapping map[DataTableColumn]string dataColumnNameMapping map[datatable.DataTableColumn]string
dataLineFormat string dataLineFormat string
builder *strings.Builder builder *strings.Builder
} }
@@ -53,7 +54,7 @@ func (t *ezBookKeepingTransactionPlainTextDataTable) HeaderLineColumnNames() []s
} }
// DataRowIterator returns the iterator of data row // DataRowIterator returns the iterator of data row
func (t *ezBookKeepingTransactionPlainTextDataTable) DataRowIterator() ImportedDataRowIterator { func (t *ezBookKeepingTransactionPlainTextDataTable) DataRowIterator() datatable.ImportedDataRowIterator {
return &ezBookKeepingTransactionPlainTextDataRowIterator{ return &ezBookKeepingTransactionPlainTextDataRowIterator{
dataTable: t, dataTable: t,
currentIndex: 0, currentIndex: 0,
@@ -90,7 +91,7 @@ func (t *ezBookKeepingTransactionPlainTextDataRowIterator) HasNext() bool {
} }
// Next returns the next imported data row // Next returns the next imported data row
func (t *ezBookKeepingTransactionPlainTextDataRowIterator) Next() ImportedDataRow { func (t *ezBookKeepingTransactionPlainTextDataRowIterator) Next() datatable.ImportedDataRow {
if t.currentIndex+1 >= len(t.dataTable.allLines) { if t.currentIndex+1 >= len(t.dataTable.allLines) {
return nil return nil
} }
@@ -106,7 +107,7 @@ func (t *ezBookKeepingTransactionPlainTextDataRowIterator) Next() ImportedDataRo
} }
// AppendTransaction appends the specified transaction to data builder // AppendTransaction appends the specified transaction to data builder
func (b *ezBookKeepingTransactionPlainTextDataTableBuilder) AppendTransaction(data map[DataTableColumn]string) { func (b *ezBookKeepingTransactionPlainTextDataTableBuilder) AppendTransaction(data map[datatable.DataTableColumn]string) {
dataRowParams := make([]any, len(b.columns)) dataRowParams := make([]any, len(b.columns))
for i := 0; i < len(b.columns); i++ { for i := 0; i < len(b.columns); i++ {
@@ -186,7 +187,7 @@ func createNewezbookkeepingTransactionPlainTextDataTable(content string, columnS
}, nil }, nil
} }
func createNewezbookkeepingTransactionPlainTextDataTableBuilder(transactionCount int, columns []DataTableColumn, dataColumnNameMapping map[DataTableColumn]string, columnSeparator string, lineSeparator string) *ezBookKeepingTransactionPlainTextDataTableBuilder { func createNewezbookkeepingTransactionPlainTextDataTableBuilder(transactionCount int, columns []datatable.DataTableColumn, dataColumnNameMapping map[datatable.DataTableColumn]string, columnSeparator string, lineSeparator string) *ezBookKeepingTransactionPlainTextDataTableBuilder {
var builder strings.Builder var builder strings.Builder
builder.Grow(transactionCount * 100) builder.Grow(transactionCount * 100)
@@ -0,0 +1,15 @@
package _default
// ezBookKeepingTransactionDataTSVFileConverter defines the structure of TSV file converter
type ezBookKeepingTransactionDataTSVFileConverter struct {
ezBookKeepingTransactionDataPlainTextConverter
}
// Initialize an ezbookkeeping transaction data tsv file converter singleton instance
var (
EzBookKeepingTransactionDataTSVFileConverter = &ezBookKeepingTransactionDataTSVFileConverter{
ezBookKeepingTransactionDataPlainTextConverter{
columnSeparator: "\t",
},
}
)
@@ -1,34 +0,0 @@
package converters
// ezBookKeepingTransactionDataCSVFileConverter defines the structure of CSV file converter
type ezBookKeepingTransactionDataCSVFileConverter struct {
ezBookKeepingTransactionDataPlainTextExporter
ezBookKeepingTransactionDataPlainTextImporter
}
// Initialize an ezbookkeeping transaction data csv file converter singleton instance
var (
EzBookKeepingTransactionDataCSVFileConverter = &ezBookKeepingTransactionDataCSVFileConverter{
ezBookKeepingTransactionDataPlainTextExporter{
DataTableTransactionDataExporter: DataTableTransactionDataExporter{
dataColumnMapping: ezbookkeepingDataColumnNameMapping,
transactionTypeMapping: ezbookkeepingTransactionTypeNameMapping,
geoLocationSeparator: " ",
transactionTagSeparator: ";",
},
columns: ezbookkeepingDataColumns,
columnSeparator: ",",
lineSeparator: "\n",
},
ezBookKeepingTransactionDataPlainTextImporter{
DataTableTransactionDataImporter: DataTableTransactionDataImporter{
dataColumnMapping: ezbookkeepingDataColumnNameMapping,
transactionTypeMapping: ezbookkeepingTransactionTypeNameMapping,
geoLocationSeparator: " ",
transactionTagSeparator: ";",
},
columnSeparator: ",",
lineSeparator: "\n",
},
}
)
@@ -1,85 +0,0 @@
package converters
import (
"github.com/mayswind/ezbookkeeping/pkg/core"
"github.com/mayswind/ezbookkeeping/pkg/models"
)
// ezBookKeepingTransactionDataPlainTextExporter defines the structure of ezbookkeeping plain text exporter for transaction data
type ezBookKeepingTransactionDataPlainTextExporter struct {
DataTableTransactionDataExporter
columns []DataTableColumn
columnSeparator string
lineSeparator string
}
// ezBookKeepingTransactionDataPlainTextImporter defines the structure of ezbookkeeping plain text importer for transaction data
type ezBookKeepingTransactionDataPlainTextImporter struct {
DataTableTransactionDataImporter
columnSeparator string
lineSeparator string
}
var ezbookkeepingDataColumnNameMapping = map[DataTableColumn]string{
DATA_TABLE_TRANSACTION_TIME: "Time",
DATA_TABLE_TRANSACTION_TIMEZONE: "Timezone",
DATA_TABLE_TRANSACTION_TYPE: "Type",
DATA_TABLE_CATEGORY: "Category",
DATA_TABLE_SUB_CATEGORY: "Sub Category",
DATA_TABLE_ACCOUNT_NAME: "Account",
DATA_TABLE_ACCOUNT_CURRENCY: "Account Currency",
DATA_TABLE_AMOUNT: "Amount",
DATA_TABLE_RELATED_ACCOUNT_NAME: "Account2",
DATA_TABLE_RELATED_ACCOUNT_CURRENCY: "Account2 Currency",
DATA_TABLE_RELATED_AMOUNT: "Account2 Amount",
DATA_TABLE_GEOGRAPHIC_LOCATION: "Geographic Location",
DATA_TABLE_TAGS: "Tags",
DATA_TABLE_DESCRIPTION: "Description",
}
var ezbookkeepingTransactionTypeNameMapping = map[models.TransactionType]string{
models.TRANSACTION_TYPE_MODIFY_BALANCE: "Balance Modification",
models.TRANSACTION_TYPE_INCOME: "Income",
models.TRANSACTION_TYPE_EXPENSE: "Expense",
models.TRANSACTION_TYPE_TRANSFER: "Transfer",
}
var ezbookkeepingDataColumns = []DataTableColumn{
DATA_TABLE_TRANSACTION_TIME,
DATA_TABLE_TRANSACTION_TIMEZONE,
DATA_TABLE_TRANSACTION_TYPE,
DATA_TABLE_CATEGORY,
DATA_TABLE_SUB_CATEGORY,
DATA_TABLE_ACCOUNT_NAME,
DATA_TABLE_ACCOUNT_CURRENCY,
DATA_TABLE_AMOUNT,
DATA_TABLE_RELATED_ACCOUNT_NAME,
DATA_TABLE_RELATED_ACCOUNT_CURRENCY,
DATA_TABLE_RELATED_AMOUNT,
DATA_TABLE_GEOGRAPHIC_LOCATION,
DATA_TABLE_TAGS,
DATA_TABLE_DESCRIPTION,
}
// ToExportedContent returns the exported transaction plain text data
func (c *ezBookKeepingTransactionDataPlainTextExporter) ToExportedContent(ctx core.Context, uid int64, transactions []*models.Transaction, accountMap map[int64]*models.Account, categoryMap map[int64]*models.TransactionCategory, tagMap map[int64]*models.TransactionTag, allTagIndexes map[int64][]int64) ([]byte, error) {
dataTableBuilder := createNewezbookkeepingTransactionPlainTextDataTableBuilder(len(transactions), c.columns, c.dataColumnMapping, c.columnSeparator, c.lineSeparator)
err := c.buildExportedContent(ctx, dataTableBuilder, uid, transactions, accountMap, categoryMap, tagMap, allTagIndexes)
if err != nil {
return nil, err
}
return []byte(dataTableBuilder.String()), nil
}
// ParseImportedData returns the imported data by parsing the transaction plain text data
func (c *ezBookKeepingTransactionDataPlainTextImporter) ParseImportedData(ctx core.Context, user *models.User, data []byte, defaultTimezoneOffset int16, accountMap map[string]*models.Account, categoryMap map[string]*models.TransactionCategory, tagMap map[string]*models.TransactionTag) (models.ImportedTransactionSlice, []*models.Account, []*models.TransactionCategory, []*models.TransactionTag, error) {
dataTable, err := createNewezbookkeepingTransactionPlainTextDataTable(string(data), c.columnSeparator, c.lineSeparator)
if err != nil {
return nil, nil, nil, nil, err
}
return c.parseImportedData(ctx, user, dataTable, defaultTimezoneOffset, accountMap, categoryMap, tagMap)
}
@@ -1,34 +0,0 @@
package converters
// ezBookKeepingTransactionDataTSVFileConverter defines the structure of TSV file converter
type ezBookKeepingTransactionDataTSVFileConverter struct {
ezBookKeepingTransactionDataPlainTextExporter
ezBookKeepingTransactionDataPlainTextImporter
}
// Initialize an ezbookkeeping transaction data tsv file converter singleton instance
var (
EzBookKeepingTransactionDataTSVFileConverter = &ezBookKeepingTransactionDataTSVFileConverter{
ezBookKeepingTransactionDataPlainTextExporter{
DataTableTransactionDataExporter: DataTableTransactionDataExporter{
dataColumnMapping: ezbookkeepingDataColumnNameMapping,
transactionTypeMapping: ezbookkeepingTransactionTypeNameMapping,
geoLocationSeparator: " ",
transactionTagSeparator: ";",
},
columns: ezbookkeepingDataColumns,
columnSeparator: "\t",
lineSeparator: "\n",
},
ezBookKeepingTransactionDataPlainTextImporter{
DataTableTransactionDataImporter: DataTableTransactionDataImporter{
dataColumnMapping: ezbookkeepingDataColumnNameMapping,
transactionTypeMapping: ezbookkeepingTransactionTypeNameMapping,
geoLocationSeparator: " ",
transactionTagSeparator: ";",
},
columnSeparator: "\t",
lineSeparator: "\n",
},
}
)
@@ -1,10 +1,11 @@
package converters package feidee
import ( import (
"encoding/csv" "encoding/csv"
"io" "io"
"strings" "strings"
"github.com/mayswind/ezbookkeeping/pkg/converters/datatable"
"github.com/mayswind/ezbookkeeping/pkg/core" "github.com/mayswind/ezbookkeeping/pkg/core"
"github.com/mayswind/ezbookkeeping/pkg/errs" "github.com/mayswind/ezbookkeeping/pkg/errs"
"github.com/mayswind/ezbookkeeping/pkg/log" "github.com/mayswind/ezbookkeeping/pkg/log"
@@ -15,15 +16,11 @@ const feideeMymoneyTransactionDataCsvFileHeader = "随手记导出文件(headers
const feideeMymoneyTransactionDataCsvFileHeaderWithUtf8Bom = "\xEF\xBB\xBF" + feideeMymoneyTransactionDataCsvFileHeader const feideeMymoneyTransactionDataCsvFileHeaderWithUtf8Bom = "\xEF\xBB\xBF" + feideeMymoneyTransactionDataCsvFileHeader
// feideeMymoneyTransactionDataCsvImporter defines the structure of feidee mymoney csv importer for transaction data // feideeMymoneyTransactionDataCsvImporter defines the structure of feidee mymoney csv importer for transaction data
type feideeMymoneyTransactionDataCsvImporter struct { type feideeMymoneyTransactionDataCsvImporter struct{}
transactionTypeMapping map[models.TransactionType]string
}
// Initialize a feidee mymoney transaction data csv file importer singleton instance // Initialize a feidee mymoney transaction data csv file importer singleton instance
var ( var (
FeideeMymoneyTransactionDataCsvImporter = &feideeMymoneyTransactionDataCsvImporter{ FeideeMymoneyTransactionDataCsvImporter = &feideeMymoneyTransactionDataCsvImporter{}
transactionTypeMapping: feideeMymoneyTransactionTypeNameMapping,
}
) )
// ParseImportedData returns the imported data by parsing the feidee mymoney transaction csv data // ParseImportedData returns the imported data by parsing the feidee mymoney transaction csv data
@@ -68,41 +65,36 @@ func (c *feideeMymoneyTransactionDataCsvImporter) ParseImportedData(ctx core.Con
return nil, nil, nil, nil, errs.ErrMissingRequiredFieldInHeaderRow return nil, nil, nil, nil, errs.ErrMissingRequiredFieldInHeaderRow
} }
newColumns := make([]DataTableColumn, 0, 11) newColumns := make([]datatable.DataTableColumn, 0, 11)
newColumns = append(newColumns, DATA_TABLE_TRANSACTION_TYPE) newColumns = append(newColumns, datatable.DATA_TABLE_TRANSACTION_TYPE)
newColumns = append(newColumns, DATA_TABLE_TRANSACTION_TIME) newColumns = append(newColumns, datatable.DATA_TABLE_TRANSACTION_TIME)
if categoryColumnExists { if categoryColumnExists {
newColumns = append(newColumns, DATA_TABLE_CATEGORY) newColumns = append(newColumns, datatable.DATA_TABLE_CATEGORY)
} }
newColumns = append(newColumns, DATA_TABLE_SUB_CATEGORY) newColumns = append(newColumns, datatable.DATA_TABLE_SUB_CATEGORY)
newColumns = append(newColumns, DATA_TABLE_ACCOUNT_NAME) newColumns = append(newColumns, datatable.DATA_TABLE_ACCOUNT_NAME)
if accountCurrencyColumnExists { if accountCurrencyColumnExists {
newColumns = append(newColumns, DATA_TABLE_ACCOUNT_CURRENCY) newColumns = append(newColumns, datatable.DATA_TABLE_ACCOUNT_CURRENCY)
} }
newColumns = append(newColumns, DATA_TABLE_AMOUNT) newColumns = append(newColumns, datatable.DATA_TABLE_AMOUNT)
newColumns = append(newColumns, DATA_TABLE_RELATED_ACCOUNT_NAME) newColumns = append(newColumns, datatable.DATA_TABLE_RELATED_ACCOUNT_NAME)
if accountCurrencyColumnExists { if accountCurrencyColumnExists {
newColumns = append(newColumns, DATA_TABLE_RELATED_ACCOUNT_CURRENCY) newColumns = append(newColumns, datatable.DATA_TABLE_RELATED_ACCOUNT_CURRENCY)
} }
newColumns = append(newColumns, DATA_TABLE_RELATED_AMOUNT) newColumns = append(newColumns, datatable.DATA_TABLE_RELATED_AMOUNT)
if descriptionColumnExists { if descriptionColumnExists {
newColumns = append(newColumns, DATA_TABLE_DESCRIPTION) newColumns = append(newColumns, datatable.DATA_TABLE_DESCRIPTION)
} }
dataTable, err := createNewWritableDataTable(newColumns) dataTable := datatable.CreateNewWritableDataTable(newColumns)
transferTransactionsMap := make(map[string]map[datatable.DataTableColumn]string, 0)
if err != nil {
return nil, nil, nil, nil, err
}
transferTransactionsMap := make(map[string]map[DataTableColumn]string, 0)
for i := 1; i < len(allLines); i++ { for i := 1; i < len(allLines); i++ {
items := allLines[i] items := allLines[i]
@@ -132,20 +124,20 @@ func (c *feideeMymoneyTransactionDataCsvImporter) ParseImportedData(ctx core.Con
return nil, nil, nil, nil, errs.ErrFewerFieldsInDataRowThanInHeaderRow return nil, nil, nil, nil, errs.ErrFewerFieldsInDataRowThanInHeaderRow
} }
transactionType := data[DATA_TABLE_TRANSACTION_TYPE] transactionType := data[datatable.DATA_TABLE_TRANSACTION_TYPE]
if transactionType == "余额变更" || transactionType == "收入" || transactionType == "支出" { if transactionType == "余额变更" || transactionType == "收入" || transactionType == "支出" {
if transactionType == "余额变更" { if transactionType == "余额变更" {
data[DATA_TABLE_TRANSACTION_TYPE] = c.transactionTypeMapping[models.TRANSACTION_TYPE_MODIFY_BALANCE] data[datatable.DATA_TABLE_TRANSACTION_TYPE] = feideeMymoneyTransactionTypeNameMapping[models.TRANSACTION_TYPE_MODIFY_BALANCE]
} else if transactionType == "收入" { } else if transactionType == "收入" {
data[DATA_TABLE_TRANSACTION_TYPE] = c.transactionTypeMapping[models.TRANSACTION_TYPE_INCOME] data[datatable.DATA_TABLE_TRANSACTION_TYPE] = feideeMymoneyTransactionTypeNameMapping[models.TRANSACTION_TYPE_INCOME]
} else if transactionType == "支出" { } else if transactionType == "支出" {
data[DATA_TABLE_TRANSACTION_TYPE] = c.transactionTypeMapping[models.TRANSACTION_TYPE_EXPENSE] data[datatable.DATA_TABLE_TRANSACTION_TYPE] = feideeMymoneyTransactionTypeNameMapping[models.TRANSACTION_TYPE_EXPENSE]
} }
data[DATA_TABLE_RELATED_ACCOUNT_NAME] = "" data[datatable.DATA_TABLE_RELATED_ACCOUNT_NAME] = ""
data[DATA_TABLE_RELATED_ACCOUNT_CURRENCY] = "" data[datatable.DATA_TABLE_RELATED_ACCOUNT_CURRENCY] = ""
data[DATA_TABLE_RELATED_AMOUNT] = "" data[datatable.DATA_TABLE_RELATED_AMOUNT] = ""
dataTable.Add(data) dataTable.Add(data)
} else if transactionType == "转入" || transactionType == "转出" { } else if transactionType == "转入" || transactionType == "转出" {
if relatedId == "" { if relatedId == "" {
@@ -160,18 +152,18 @@ func (c *feideeMymoneyTransactionDataCsvImporter) ParseImportedData(ctx core.Con
continue continue
} }
if transactionType == "转入" && relatedData[DATA_TABLE_TRANSACTION_TYPE] == "转出" { if transactionType == "转入" && relatedData[datatable.DATA_TABLE_TRANSACTION_TYPE] == "转出" {
relatedData[DATA_TABLE_TRANSACTION_TYPE] = c.transactionTypeMapping[models.TRANSACTION_TYPE_TRANSFER] relatedData[datatable.DATA_TABLE_TRANSACTION_TYPE] = feideeMymoneyTransactionTypeNameMapping[models.TRANSACTION_TYPE_TRANSFER]
relatedData[DATA_TABLE_RELATED_ACCOUNT_NAME] = data[DATA_TABLE_ACCOUNT_NAME] relatedData[datatable.DATA_TABLE_RELATED_ACCOUNT_NAME] = data[datatable.DATA_TABLE_ACCOUNT_NAME]
relatedData[DATA_TABLE_RELATED_ACCOUNT_CURRENCY] = data[DATA_TABLE_ACCOUNT_CURRENCY] relatedData[datatable.DATA_TABLE_RELATED_ACCOUNT_CURRENCY] = data[datatable.DATA_TABLE_ACCOUNT_CURRENCY]
relatedData[DATA_TABLE_RELATED_AMOUNT] = data[DATA_TABLE_AMOUNT] relatedData[datatable.DATA_TABLE_RELATED_AMOUNT] = data[datatable.DATA_TABLE_AMOUNT]
dataTable.Add(relatedData) dataTable.Add(relatedData)
delete(transferTransactionsMap, relatedId) delete(transferTransactionsMap, relatedId)
} else if transactionType == "转出" && relatedData[DATA_TABLE_TRANSACTION_TYPE] == "转入" { } else if transactionType == "转出" && relatedData[datatable.DATA_TABLE_TRANSACTION_TYPE] == "转入" {
data[DATA_TABLE_TRANSACTION_TYPE] = c.transactionTypeMapping[models.TRANSACTION_TYPE_TRANSFER] data[datatable.DATA_TABLE_TRANSACTION_TYPE] = feideeMymoneyTransactionTypeNameMapping[models.TRANSACTION_TYPE_TRANSFER]
data[DATA_TABLE_RELATED_ACCOUNT_NAME] = relatedData[DATA_TABLE_ACCOUNT_NAME] data[datatable.DATA_TABLE_RELATED_ACCOUNT_NAME] = relatedData[datatable.DATA_TABLE_ACCOUNT_NAME]
data[DATA_TABLE_RELATED_ACCOUNT_CURRENCY] = relatedData[DATA_TABLE_ACCOUNT_CURRENCY] data[datatable.DATA_TABLE_RELATED_ACCOUNT_CURRENCY] = relatedData[datatable.DATA_TABLE_ACCOUNT_CURRENCY]
data[DATA_TABLE_RELATED_AMOUNT] = relatedData[DATA_TABLE_AMOUNT] data[datatable.DATA_TABLE_RELATED_AMOUNT] = relatedData[datatable.DATA_TABLE_AMOUNT]
dataTable.Add(data) dataTable.Add(data)
delete(transferTransactionsMap, relatedId) delete(transferTransactionsMap, relatedId)
} else { } else {
@@ -189,13 +181,13 @@ func (c *feideeMymoneyTransactionDataCsvImporter) ParseImportedData(ctx core.Con
return nil, nil, nil, nil, errs.ErrFoundRecordNotHasRelatedRecord return nil, nil, nil, nil, errs.ErrFoundRecordNotHasRelatedRecord
} }
dataTableImporter := DataTableTransactionDataImporter{ dataTableImporter := datatable.CreateNewSimpleDataTableTransactionDataImporterWithPostProcessFunc(
dataColumnMapping: dataTable.GetDataColumnMapping(), dataTable.GetDataColumnMapping(),
transactionTypeMapping: c.transactionTypeMapping, feideeMymoneyTransactionTypeNameMapping,
postProcessFunc: feideeMymoneyTransactionDataImporterPostProcess, feideeMymoneyTransactionDataImporterPostProcess,
} )
return dataTableImporter.parseImportedData(ctx, user, dataTable, defaultTimezoneOffset, accountMap, categoryMap, tagMap) return dataTableImporter.ParseImportedData(ctx, user, dataTable, defaultTimezoneOffset, accountMap, categoryMap, tagMap)
} }
func (c *feideeMymoneyTransactionDataCsvImporter) parseAllLinesFromCsvData(ctx core.Context, content string) ([][]string, error) { func (c *feideeMymoneyTransactionDataCsvImporter) parseAllLinesFromCsvData(ctx core.Context, content string) ([][]string, error) {
@@ -246,40 +238,40 @@ func (c *feideeMymoneyTransactionDataCsvImporter) parseTransactionData(
descriptionColumnExists bool, descriptionColumnExists bool,
relatedIdColumnIdx int, relatedIdColumnIdx int,
relatedIdColumnExists bool, relatedIdColumnExists bool,
) (map[DataTableColumn]string, string) { ) (map[datatable.DataTableColumn]string, string) {
data := make(map[DataTableColumn]string, 11) data := make(map[datatable.DataTableColumn]string, 11)
relatedId := "" relatedId := ""
if timeColumnExists && timeColumnIdx < len(items) { if timeColumnExists && timeColumnIdx < len(items) {
data[DATA_TABLE_TRANSACTION_TIME] = items[timeColumnIdx] data[datatable.DATA_TABLE_TRANSACTION_TIME] = items[timeColumnIdx]
} }
if typeColumnExists && typeColumnIdx < len(items) { if typeColumnExists && typeColumnIdx < len(items) {
data[DATA_TABLE_TRANSACTION_TYPE] = items[typeColumnIdx] data[datatable.DATA_TABLE_TRANSACTION_TYPE] = items[typeColumnIdx]
} }
if categoryColumnExists && categoryColumnIdx < len(items) { if categoryColumnExists && categoryColumnIdx < len(items) {
data[DATA_TABLE_CATEGORY] = items[categoryColumnIdx] data[datatable.DATA_TABLE_CATEGORY] = items[categoryColumnIdx]
} }
if subCategoryColumnExists && subCategoryColumnIdx < len(items) { if subCategoryColumnExists && subCategoryColumnIdx < len(items) {
data[DATA_TABLE_SUB_CATEGORY] = items[subCategoryColumnIdx] data[datatable.DATA_TABLE_SUB_CATEGORY] = items[subCategoryColumnIdx]
} }
if accountColumnExists && accountColumnIdx < len(items) { if accountColumnExists && accountColumnIdx < len(items) {
data[DATA_TABLE_ACCOUNT_NAME] = items[accountColumnIdx] data[datatable.DATA_TABLE_ACCOUNT_NAME] = items[accountColumnIdx]
} }
if accountCurrencyColumnExists && accountCurrencyColumnIdx < len(items) { if accountCurrencyColumnExists && accountCurrencyColumnIdx < len(items) {
data[DATA_TABLE_ACCOUNT_CURRENCY] = items[accountCurrencyColumnIdx] data[datatable.DATA_TABLE_ACCOUNT_CURRENCY] = items[accountCurrencyColumnIdx]
} }
if amountColumnExists && amountColumnIdx < len(items) { if amountColumnExists && amountColumnIdx < len(items) {
data[DATA_TABLE_AMOUNT] = items[amountColumnIdx] data[datatable.DATA_TABLE_AMOUNT] = items[amountColumnIdx]
} }
if descriptionColumnExists && descriptionColumnIdx < len(items) { if descriptionColumnExists && descriptionColumnIdx < len(items) {
data[DATA_TABLE_DESCRIPTION] = items[descriptionColumnIdx] data[datatable.DATA_TABLE_DESCRIPTION] = items[descriptionColumnIdx]
} }
if relatedIdColumnExists && relatedIdColumnIdx < len(items) { if relatedIdColumnExists && relatedIdColumnIdx < len(items) {
@@ -289,7 +281,7 @@ func (c *feideeMymoneyTransactionDataCsvImporter) parseTransactionData(
return data, relatedId return data, relatedId
} }
func (c *feideeMymoneyTransactionDataCsvImporter) getRelatedIds(transferTransactionsMap map[string]map[DataTableColumn]string) string { func (c *feideeMymoneyTransactionDataCsvImporter) getRelatedIds(transferTransactionsMap map[string]map[datatable.DataTableColumn]string) string {
builder := strings.Builder{} builder := strings.Builder{}
for relatedId := range transferTransactionsMap { for relatedId := range transferTransactionsMap {
@@ -1,4 +1,4 @@
package converters package feidee
import ( import (
"testing" "testing"
@@ -1,4 +1,4 @@
package converters package feidee
import ( import (
"bytes" "bytes"
@@ -6,6 +6,7 @@ import (
"github.com/shakinm/xlsReader/xls" "github.com/shakinm/xlsReader/xls"
"github.com/mayswind/ezbookkeeping/pkg/converters/datatable"
"github.com/mayswind/ezbookkeeping/pkg/errs" "github.com/mayswind/ezbookkeeping/pkg/errs"
"github.com/mayswind/ezbookkeeping/pkg/utils" "github.com/mayswind/ezbookkeeping/pkg/utils"
) )
@@ -53,7 +54,7 @@ func (t *feideeMymoneyTransactionExcelFileDataTable) HeaderLineColumnNames() []s
} }
// DataRowIterator returns the iterator of data row // DataRowIterator returns the iterator of data row
func (t *feideeMymoneyTransactionExcelFileDataTable) DataRowIterator() ImportedDataRowIterator { func (t *feideeMymoneyTransactionExcelFileDataTable) DataRowIterator() datatable.ImportedDataRowIterator {
return &feideeMymoneyTransactionExcelFileDataRowIterator{ return &feideeMymoneyTransactionExcelFileDataRowIterator{
dataTable: t, dataTable: t,
currentTableIndex: 0, currentTableIndex: 0,
@@ -141,7 +142,7 @@ func (t *feideeMymoneyTransactionExcelFileDataRowIterator) HasNext() bool {
} }
// Next returns the next imported data row // Next returns the next imported data row
func (t *feideeMymoneyTransactionExcelFileDataRowIterator) Next() ImportedDataRow { func (t *feideeMymoneyTransactionExcelFileDataRowIterator) Next() datatable.ImportedDataRow {
allSheets := t.dataTable.workbook.GetSheets() allSheets := t.dataTable.workbook.GetSheets()
currentRowIndexInTable := t.currentRowIndexInTable currentRowIndexInTable := t.currentRowIndexInTable
@@ -1,19 +1,20 @@
package converters package feidee
import ( import (
"github.com/mayswind/ezbookkeeping/pkg/converters/datatable"
"github.com/mayswind/ezbookkeeping/pkg/core" "github.com/mayswind/ezbookkeeping/pkg/core"
"github.com/mayswind/ezbookkeeping/pkg/models" "github.com/mayswind/ezbookkeeping/pkg/models"
) )
var feideeMymoneyDataColumnNameMapping = map[DataTableColumn]string{ var feideeMymoneyDataColumnNameMapping = map[datatable.DataTableColumn]string{
DATA_TABLE_TRANSACTION_TIME: "日期", datatable.DATA_TABLE_TRANSACTION_TIME: "日期",
DATA_TABLE_TRANSACTION_TYPE: "交易类型", datatable.DATA_TABLE_TRANSACTION_TYPE: "交易类型",
DATA_TABLE_CATEGORY: "分类", datatable.DATA_TABLE_CATEGORY: "分类",
DATA_TABLE_SUB_CATEGORY: "子分类", datatable.DATA_TABLE_SUB_CATEGORY: "子分类",
DATA_TABLE_ACCOUNT_NAME: "账户1", datatable.DATA_TABLE_ACCOUNT_NAME: "账户1",
DATA_TABLE_AMOUNT: "金额", datatable.DATA_TABLE_AMOUNT: "金额",
DATA_TABLE_RELATED_ACCOUNT_NAME: "账户2", datatable.DATA_TABLE_RELATED_ACCOUNT_NAME: "账户2",
DATA_TABLE_DESCRIPTION: "备注", datatable.DATA_TABLE_DESCRIPTION: "备注",
} }
var feideeMymoneyTransactionTypeNameMapping = map[models.TransactionType]string{ var feideeMymoneyTransactionTypeNameMapping = map[models.TransactionType]string{
@@ -1,24 +1,19 @@
package converters package feidee
import ( import (
"github.com/mayswind/ezbookkeeping/pkg/converters/datatable"
"github.com/mayswind/ezbookkeeping/pkg/core" "github.com/mayswind/ezbookkeeping/pkg/core"
"github.com/mayswind/ezbookkeeping/pkg/models" "github.com/mayswind/ezbookkeeping/pkg/models"
) )
// feideeMymoneyTransactionDataXlsImporter defines the structure of feidee mymoney xls importer for transaction data // feideeMymoneyTransactionDataXlsImporter defines the structure of feidee mymoney xls importer for transaction data
type feideeMymoneyTransactionDataXlsImporter struct { type feideeMymoneyTransactionDataXlsImporter struct {
DataTableTransactionDataImporter datatable.DataTableTransactionDataImporter
} }
// Initialize a feidee mymoney transaction data xls file importer singleton instance // Initialize a feidee mymoney transaction data xls file importer singleton instance
var ( var (
FeideeMymoneyTransactionDataXlsImporter = &feideeMymoneyTransactionDataXlsImporter{ FeideeMymoneyTransactionDataXlsImporter = &feideeMymoneyTransactionDataXlsImporter{}
DataTableTransactionDataImporter{
dataColumnMapping: feideeMymoneyDataColumnNameMapping,
transactionTypeMapping: feideeMymoneyTransactionTypeNameMapping,
postProcessFunc: feideeMymoneyTransactionDataImporterPostProcess,
},
}
) )
// ParseImportedData returns the imported data by parsing the feidee mymoney transaction xls data // ParseImportedData returns the imported data by parsing the feidee mymoney transaction xls data
@@ -29,5 +24,11 @@ func (c *feideeMymoneyTransactionDataXlsImporter) ParseImportedData(ctx core.Con
return nil, nil, nil, nil, err return nil, nil, nil, nil, err
} }
return c.parseImportedData(ctx, user, dataTable, defaultTimezoneOffset, accountMap, categoryMap, tagMap) dataTableImporter := datatable.CreateNewSimpleDataTableTransactionDataImporterWithPostProcessFunc(
feideeMymoneyDataColumnNameMapping,
feideeMymoneyTransactionTypeNameMapping,
feideeMymoneyTransactionDataImporterPostProcess,
)
return dataTableImporter.ParseImportedData(ctx, user, dataTable, defaultTimezoneOffset, accountMap, categoryMap, tagMap)
} }
@@ -1,4 +1,4 @@
package converters package feidee
import ( import (
"os" "os"
@@ -21,7 +21,7 @@ func TestFeideeMymoneyTransactionDataXlsImporterParseImportedData_MinimumValidDa
DefaultCurrency: "CNY", DefaultCurrency: "CNY",
} }
testdata, err := os.ReadFile("../../testdata/feidee_mymoney_test_file.xls") testdata, err := os.ReadFile("../../../testdata/feidee_mymoney_test_file.xls")
assert.Nil(t, err) assert.Nil(t, err)
allNewTransactions, allNewAccounts, allNewSubCategories, allNewTags, err := converter.ParseImportedData(context, user, testdata, 0, nil, nil, nil) allNewTransactions, allNewAccounts, allNewSubCategories, allNewTags, err := converter.ParseImportedData(context, user, testdata, 0, nil, nil, nil)
+14 -9
View File
@@ -1,28 +1,33 @@
package converters package converters
import "github.com/mayswind/ezbookkeeping/pkg/errs" import (
"github.com/mayswind/ezbookkeeping/pkg/converters/base"
"github.com/mayswind/ezbookkeeping/pkg/converters/default"
"github.com/mayswind/ezbookkeeping/pkg/converters/feidee"
"github.com/mayswind/ezbookkeeping/pkg/errs"
)
// GetTransactionDataExporter returns the transaction data exporter according to the file type // GetTransactionDataExporter returns the transaction data exporter according to the file type
func GetTransactionDataExporter(fileType string) TransactionDataExporter { func GetTransactionDataExporter(fileType string) base.TransactionDataExporter {
if fileType == "csv" { if fileType == "csv" {
return EzBookKeepingTransactionDataCSVFileConverter return _default.EzBookKeepingTransactionDataCSVFileConverter
} else if fileType == "tsv" { } else if fileType == "tsv" {
return EzBookKeepingTransactionDataTSVFileConverter return _default.EzBookKeepingTransactionDataTSVFileConverter
} else { } else {
return nil return nil
} }
} }
// GetTransactionDataImporter returns the transaction data importer according to the file type // GetTransactionDataImporter returns the transaction data importer according to the file type
func GetTransactionDataImporter(fileType string) (TransactionDataImporter, error) { func GetTransactionDataImporter(fileType string) (base.TransactionDataImporter, error) {
if fileType == "ezbookkeeping_csv" { if fileType == "ezbookkeeping_csv" {
return EzBookKeepingTransactionDataCSVFileConverter, nil return _default.EzBookKeepingTransactionDataCSVFileConverter, nil
} else if fileType == "ezbookkeeping_tsv" { } else if fileType == "ezbookkeeping_tsv" {
return EzBookKeepingTransactionDataTSVFileConverter, nil return _default.EzBookKeepingTransactionDataTSVFileConverter, nil
} else if fileType == "feidee_mymoney_csv" { } else if fileType == "feidee_mymoney_csv" {
return FeideeMymoneyTransactionDataCsvImporter, nil return feidee.FeideeMymoneyTransactionDataCsvImporter, nil
} else if fileType == "feidee_mymoney_xls" { } else if fileType == "feidee_mymoney_xls" {
return FeideeMymoneyTransactionDataXlsImporter, nil return feidee.FeideeMymoneyTransactionDataXlsImporter, nil
} else { } else {
return nil, errs.ErrImportFileTypeNotSupported return nil, errs.ErrImportFileTypeNotSupported
} }