You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
83 lines
2.1 KiB
83 lines
2.1 KiB
2 years ago
|
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
|
||
|
}
|