package main import ( "encoding/xml" "github.com/aclindsa/ofxgo" "time" "fmt" "github.com/ochinchina/go-ini" "io" ) func transactionsFromXml(r io.Reader, assets ini.Section, vendors []ini.Key) ([]transaction, error) { type xmlTransaction struct { XMLName xml.Name `xml:"transaction"` Date string `xml:"Date"` TrnAmt float64 `xml:"amount"` Asset string `xml:"Asset"` Expense string `xml:"Expense,omitempty"` VendorName string `xml:"VendorName,omitempty"` Currency string `xml:"Currency"` } type transactionParent struct { XMLName xml.Name `xml:"transactions"` Transactions []xmlTransaction `xml:"transaction"` } root := new(transactionParent) d := xml.NewDecoder(r) err := d.Decode(&root) if err != nil { return nil, fmt.Errorf("failed unmarshaling xml: %w", err) } xtx := root.Transactions transactions := make([]transaction, 0) for _, t := range xtx { var expense string if t.VendorName != "" && t.Expense == "" { expense = matchPartial(vendors, t.VendorName) } time, err := time.Parse("1/02/2006", t.Date) if err != nil { return nil, fmt.Errorf("failed parsing time: %w", err) } tx := transaction { Date: time, TrnAmt: t.TrnAmt, Asset: t.Asset, Expense: expense, VendorName: t.VendorName, Currency: t.Currency, } transactions = append(transactions, tx) } return transactions, nil } func transactionsFromOfx(r io.Reader, assets ini.Section, vendors []ini.Key) ([]transaction, error) { resp, err := ofxgo.ParseResponse(r) if err != nil { return nil, err } transactions := make([]transaction, 0) for _, m := range resp.Bank { if stmt, ok := m.(*ofxgo.StatementResponse); ok { for _, t := range stmt.BankTranList.Transactions { acctId := stmt.BankAcctFrom.AcctID.String() amt, _ := t.TrnAmt.Rat.Float64() tx := transaction{ Date: t.DtPosted.Time, TrnAmt: amt, Asset: assets.GetValueWithDefault(acctId, acctId), Expense: matchPartial(vendors, t.Name.String()), VendorName: t.Name.String(), Currency: stmt.CurDef.String(), } transactions = append(transactions, tx) } } } return transactions, nil }