WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Commit 3477353

Browse files
committed
code refactor
1 parent 6c285a0 commit 3477353

16 files changed

+593
-507
lines changed

pkg/converters/alipay/alipay_transaction_csv_data_table.go

Lines changed: 90 additions & 150 deletions
Large diffs are not rendered by default.

pkg/converters/alipay/alipay_transaction_data_csv_file_importer_test.go

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,56 @@ func TestAlipayCsvFileImporterParseImportedData_ParseCategory(t *testing.T) {
364364
assert.Equal(t, "Test Category3", allNewSubTransferCategories[0].Name)
365365
}
366366

367+
func TestAlipayCsvFileImporterParseImportedData_ParseRelatedAccount(t *testing.T) {
368+
converter := AlipayAppTransactionDataCsvFileImporter
369+
context := core.NewNullContext()
370+
371+
user := &models.User{
372+
Uid: 1234567890,
373+
DefaultCurrency: "CNY",
374+
}
375+
376+
data1, err := simplifiedchinese.GB18030.NewEncoder().String("------------------------------------------------------------------------------------\n" +
377+
"导出信息:\n" +
378+
"姓名:xxx\n" +
379+
"支付宝账户:[email protected]\n" +
380+
"起始时间:[2024-01-01 00:00:00] 终止时间:[2024-09-01 23:59:59]\n" +
381+
"导出交易类型:[全部]\n" +
382+
"------------------------支付宝(中国)网络技术有限公司 电子客户回单------------------------\n" +
383+
"交易时间,商品说明,收/支,金额,收/付款方式,交易状态,\n" +
384+
"2024-09-01 03:45:07,余额宝-单次转入,不计收支,0.01,Test Account,交易成功,\n" +
385+
"2024-09-01 05:07:29,信用卡还款,不计收支,0.02,Test Account2,交易成功,\n")
386+
assert.Nil(t, err)
387+
388+
allNewTransactions, allNewAccounts, _, _, _, _, err := converter.ParseImportedData(context, user, []byte(data1), 0, nil, nil, nil, nil, nil)
389+
assert.Nil(t, err)
390+
391+
assert.Equal(t, 2, len(allNewTransactions))
392+
assert.Equal(t, 3, len(allNewAccounts))
393+
394+
assert.Equal(t, int64(1234567890), allNewTransactions[0].Uid)
395+
assert.Equal(t, int64(1), allNewTransactions[0].Amount)
396+
assert.Equal(t, "Test Account", allNewTransactions[0].OriginalSourceAccountName)
397+
assert.Equal(t, "", allNewTransactions[0].OriginalDestinationAccountName)
398+
399+
assert.Equal(t, int64(1234567890), allNewTransactions[1].Uid)
400+
assert.Equal(t, int64(2), allNewTransactions[1].Amount)
401+
assert.Equal(t, "Test Account2", allNewTransactions[1].OriginalSourceAccountName)
402+
assert.Equal(t, "", allNewTransactions[1].OriginalDestinationAccountName)
403+
404+
assert.Equal(t, int64(1234567890), allNewAccounts[0].Uid)
405+
assert.Equal(t, "Test Account", allNewAccounts[0].Name)
406+
assert.Equal(t, "CNY", allNewAccounts[0].Currency)
407+
408+
assert.Equal(t, int64(1234567890), allNewAccounts[1].Uid)
409+
assert.Equal(t, "", allNewAccounts[1].Name)
410+
assert.Equal(t, "CNY", allNewAccounts[1].Currency)
411+
412+
assert.Equal(t, int64(1234567890), allNewAccounts[2].Uid)
413+
assert.Equal(t, "Test Account2", allNewAccounts[2].Name)
414+
assert.Equal(t, "CNY", allNewAccounts[2].Currency)
415+
}
416+
367417
func TestAlipayCsvFileImporterParseImportedData_ParseDescription(t *testing.T) {
368418
converter := AlipayWebTransactionDataCsvFileImporter
369419
context := core.NewNullContext()
@@ -479,3 +529,23 @@ func TestAlipayCsvFileImporterParseImportedData_MissingRequiredColumn(t *testing
479529
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data4), 0, nil, nil, nil, nil, nil)
480530
assert.EqualError(t, err, errs.ErrMissingRequiredFieldInHeaderRow.Message)
481531
}
532+
533+
func TestAlipayCsvFileImporterParseImportedData_NoTransactionData(t *testing.T) {
534+
converter := AlipayWebTransactionDataCsvFileImporter
535+
context := core.NewNullContext()
536+
537+
user := &models.User{
538+
Uid: 1,
539+
DefaultCurrency: "CNY",
540+
}
541+
542+
// Missing Time Column
543+
data1, err := simplifiedchinese.GB18030.NewEncoder().String("支付宝交易记录明细查询\n" +
544+
"账号:[[email protected]]\n" +
545+
"起始日期:[2024-01-01 00:00:00] 终止日期:[2024-09-01 23:59:59]\n" +
546+
"---------------------------------交易记录明细列表------------------------------------\n" +
547+
"交易创建时间 ,金额(元),收/支 ,交易状态 ,\n" +
548+
"------------------------------------------------------------------------------------\n")
549+
_, _, _, _, _, _, err = converter.ParseImportedData(context, user, []byte(data1), 0, nil, nil, nil, nil, nil)
550+
assert.EqualError(t, err, errs.ErrNotFoundTransactionDataInFile.Message)
551+
}

pkg/converters/csv/csv_file_imported_data_table.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package csv
22

33
import (
44
"encoding/csv"
5+
"fmt"
56
"io"
67

78
"github.com/mayswind/ezbookkeeping/pkg/converters/datatable"
@@ -72,6 +73,11 @@ func (t *CsvFileImportedDataRowIterator) HasNext() bool {
7273
return t.currentIndex+1 < len(t.dataTable.allLines)
7374
}
7475

76+
// CurrentRowId returns current index
77+
func (t *CsvFileImportedDataRowIterator) CurrentRowId() string {
78+
return fmt.Sprintf("line#%d", t.currentIndex)
79+
}
80+
7581
// Next returns the next imported data row
7682
func (t *CsvFileImportedDataRowIterator) Next() datatable.ImportedDataRow {
7783
if t.currentIndex+1 >= len(t.dataTable.allLines) {
@@ -88,11 +94,18 @@ func (t *CsvFileImportedDataRowIterator) Next() datatable.ImportedDataRow {
8894
}
8995
}
9096

91-
// CreateNewCsvDataTable returns comma separated values data table by io readers
92-
func CreateNewCsvDataTable(ctx core.Context, reader io.Reader) (*CsvFileImportedDataTable, error) {
97+
// CreateNewCsvImportedDataTable returns comma separated values data table by io readers
98+
func CreateNewCsvImportedDataTable(ctx core.Context, reader io.Reader) (*CsvFileImportedDataTable, error) {
9399
return createNewCsvFileDataTable(ctx, reader, ',')
94100
}
95101

102+
// CreateNewCustomCsvImportedDataTable returns character separated values data table by io readers
103+
func CreateNewCustomCsvImportedDataTable(allLines [][]string) *CsvFileImportedDataTable {
104+
return &CsvFileImportedDataTable{
105+
allLines: allLines,
106+
}
107+
}
108+
96109
func createNewCsvFileDataTable(ctx core.Context, reader io.Reader, separator rune) (*CsvFileImportedDataTable, error) {
97110
csvReader := csv.NewReader(reader)
98111
csvReader.Comma = separator
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package datatable
2+
3+
// CommonDataTable defines the structure of common data table
4+
type CommonDataTable interface {
5+
// HeaderColumnCount returns the total count of column in header row
6+
HeaderColumnCount() int
7+
8+
// HasColumn returns whether the common data table has specified column name
9+
HasColumn(columnName string) bool
10+
11+
// DataRowCount returns the total count of common data row
12+
DataRowCount() int
13+
14+
// DataRowIterator returns the iterator of common data row
15+
DataRowIterator() CommonDataRowIterator
16+
}
17+
18+
// CommonDataRow defines the structure of common data row
19+
type CommonDataRow interface {
20+
// ColumnCount returns the total count of column in this data row
21+
ColumnCount() int
22+
23+
// HasData returns whether the common data row has specified column data
24+
HasData(columnName string) bool
25+
26+
// GetData returns the data in the specified column name
27+
GetData(columnName string) string
28+
}
29+
30+
// CommonDataRowIterator defines the structure of common data row iterator
31+
type CommonDataRowIterator interface {
32+
// HasNext returns whether the iterator does not reach the end
33+
HasNext() bool
34+
35+
// CurrentRowId returns current row id
36+
CurrentRowId() string
37+
38+
// Next returns the next common data row
39+
Next() CommonDataRow
40+
}
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
package datatable
2+
3+
// ImportedCommonDataTable defines the structure of imported common data table
4+
type ImportedCommonDataTable struct {
5+
innerDataTable ImportedDataTable
6+
dataColumnIndexes map[string]int
7+
}
8+
9+
// ImportedCommonDataRow defines the structure of imported common data row
10+
type ImportedCommonDataRow struct {
11+
rowData map[string]string
12+
}
13+
14+
// ImportedCommonDataRowIterator defines the structure of imported common data row iterator
15+
type ImportedCommonDataRowIterator struct {
16+
commonDataTable *ImportedCommonDataTable
17+
innerIterator ImportedDataRowIterator
18+
}
19+
20+
// HeaderColumnCount returns the total count of column in header row
21+
func (t *ImportedCommonDataTable) HeaderColumnCount() int {
22+
return len(t.innerDataTable.HeaderColumnNames())
23+
}
24+
25+
// HasColumn returns whether the data table has specified column name
26+
func (t *ImportedCommonDataTable) HasColumn(columnName string) bool {
27+
index, exists := t.dataColumnIndexes[columnName]
28+
return exists && index >= 0
29+
}
30+
31+
// DataRowCount returns the total count of common data row
32+
func (t *ImportedCommonDataTable) DataRowCount() int {
33+
return t.innerDataTable.DataRowCount()
34+
}
35+
36+
// DataRowIterator returns the iterator of common data row
37+
func (t *ImportedCommonDataTable) DataRowIterator() CommonDataRowIterator {
38+
return &ImportedCommonDataRowIterator{
39+
commonDataTable: t,
40+
innerIterator: t.innerDataTable.DataRowIterator(),
41+
}
42+
}
43+
44+
// HasData returns whether the common data row has specified column data
45+
func (r *ImportedCommonDataRow) HasData(columnName string) bool {
46+
_, exists := r.rowData[columnName]
47+
return exists
48+
}
49+
50+
// ColumnCount returns the total count of column in this data row
51+
func (r *ImportedCommonDataRow) ColumnCount() int {
52+
return len(r.rowData)
53+
}
54+
55+
// GetData returns the data in the specified column name
56+
func (r *ImportedCommonDataRow) GetData(columnName string) string {
57+
return r.rowData[columnName]
58+
}
59+
60+
// HasNext returns whether the iterator does not reach the end
61+
func (t *ImportedCommonDataRowIterator) HasNext() bool {
62+
return t.innerIterator.HasNext()
63+
}
64+
65+
// CurrentRowId returns current row id
66+
func (t *ImportedCommonDataRowIterator) CurrentRowId() string {
67+
return t.innerIterator.CurrentRowId()
68+
}
69+
70+
// Next returns the next common data row
71+
func (t *ImportedCommonDataRowIterator) Next() CommonDataRow {
72+
importedRow := t.innerIterator.Next()
73+
74+
if importedRow == nil {
75+
return nil
76+
}
77+
78+
rowData := make(map[string]string, len(t.commonDataTable.dataColumnIndexes))
79+
80+
for column, columnIndex := range t.commonDataTable.dataColumnIndexes {
81+
if columnIndex < 0 || columnIndex >= importedRow.ColumnCount() {
82+
continue
83+
}
84+
85+
value := importedRow.GetData(columnIndex)
86+
rowData[column] = value
87+
}
88+
89+
return &ImportedCommonDataRow{
90+
rowData: rowData,
91+
}
92+
}
93+
94+
// CreateNewImportedCommonDataTable returns common data table from imported data table
95+
func CreateNewImportedCommonDataTable(dataTable ImportedDataTable) *ImportedCommonDataTable {
96+
headerLineItems := dataTable.HeaderColumnNames()
97+
dataColumnIndexes := make(map[string]int, len(headerLineItems))
98+
99+
for i := 0; i < len(headerLineItems); i++ {
100+
dataColumnIndexes[headerLineItems[i]] = i
101+
}
102+
103+
return &ImportedCommonDataTable{
104+
innerDataTable: dataTable,
105+
dataColumnIndexes: dataColumnIndexes,
106+
}
107+
}

pkg/converters/datatable/imported_data_table.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ type ImportedDataRowIterator interface {
2626
// HasNext returns whether the iterator does not reach the end
2727
HasNext() bool
2828

29+
// CurrentRowId returns current row id
30+
CurrentRowId() string
31+
2932
// Next returns the next imported data row
3033
Next() ImportedDataRow
3134
}

pkg/converters/datatable/imported_transaction_data_table.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -143,13 +143,13 @@ func (t *ImportedTransactionDataRowIterator) Next(ctx core.Context, user *models
143143
}, nil
144144
}
145145

146-
// CreateImportedTransactionDataTable returns transaction data table from imported data table
147-
func CreateImportedTransactionDataTable(dataTable ImportedDataTable, dataColumnMapping map[TransactionDataTableColumn]string) *ImportedTransactionDataTable {
148-
return CreateImportedTransactionDataTableWithRowParser(dataTable, dataColumnMapping, nil)
146+
// CreateNewImportedTransactionDataTable returns transaction data table from imported data table
147+
func CreateNewImportedTransactionDataTable(dataTable ImportedDataTable, dataColumnMapping map[TransactionDataTableColumn]string) *ImportedTransactionDataTable {
148+
return CreateNewImportedTransactionDataTableWithRowParser(dataTable, dataColumnMapping, nil)
149149
}
150150

151-
// CreateImportedTransactionDataTableWithRowParser returns transaction data table from imported data table
152-
func CreateImportedTransactionDataTableWithRowParser(dataTable ImportedDataTable, dataColumnMapping map[TransactionDataTableColumn]string, rowParser TransactionDataRowParser) *ImportedTransactionDataTable {
151+
// CreateNewImportedTransactionDataTableWithRowParser returns transaction data table from imported data table
152+
func CreateNewImportedTransactionDataTableWithRowParser(dataTable ImportedDataTable, dataColumnMapping map[TransactionDataTableColumn]string, rowParser TransactionDataRowParser) *ImportedTransactionDataTable {
153153
headerLineItems := dataTable.HeaderColumnNames()
154154
headerItemMap := make(map[string]int, len(headerLineItems))
155155

pkg/converters/default/default_transaction_data_plain_text_converter.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ func (c *defaultTransactionDataPlainTextConverter) ParseImportedData(ctx core.Co
9393
return nil, nil, nil, nil, nil, nil, err
9494
}
9595

96-
transactionDataTable := datatable.CreateImportedTransactionDataTable(dataTable, ezbookkeepingDataColumnNameMapping)
96+
transactionDataTable := datatable.CreateNewImportedTransactionDataTable(dataTable, ezbookkeepingDataColumnNameMapping)
9797

9898
dataTableImporter := datatable.CreateNewImporter(
9999
ezbookkeepingTransactionTypeNameMapping,

pkg/converters/default/default_transaction_plain_text_data_table.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,11 @@ func (t *defaultPlainTextDataRowIterator) HasNext() bool {
7878
return t.currentIndex+1 < len(t.dataTable.allLines)
7979
}
8080

81+
// CurrentRowId returns current index
82+
func (t *defaultPlainTextDataRowIterator) CurrentRowId() string {
83+
return fmt.Sprintf("line#%d", t.currentIndex)
84+
}
85+
8186
// Next returns the next imported data row
8287
func (t *defaultPlainTextDataRowIterator) Next() datatable.ImportedDataRow {
8388
if t.currentIndex+1 >= len(t.dataTable.allLines) {

pkg/converters/excel/excel_file_imported_data_table.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package excel
22

33
import (
44
"bytes"
5+
"fmt"
56

67
"github.com/shakinm/xlsReader/xls"
78

@@ -115,6 +116,11 @@ func (t *ExcelFileDataRowIterator) HasNext() bool {
115116
return false
116117
}
117118

119+
// CurrentRowId returns current index
120+
func (t *ExcelFileDataRowIterator) CurrentRowId() string {
121+
return fmt.Sprintf("table#%d-row#%d", t.currentTableIndex, t.currentRowIndexInTable)
122+
}
123+
118124
// Next returns the next imported data row
119125
func (t *ExcelFileDataRowIterator) Next() datatable.ImportedDataRow {
120126
allSheets := t.dataTable.workbook.GetSheets()

0 commit comments

Comments
 (0)