package main import ( "flag" "os" "bufio" "log" "strings" "io" "text/template" "sort" "github.com/aclindsa/ofxgo" "github.com/ochinchina/go-ini" ) func matchVendor(keys []ini.Key, givenName string) string { for _, k := range keys { v := k.ValueWithDefault("") if strings.Contains(givenName, k.Name()) { return v } } return "Expenses" } func generateLedgerTransactions(transactions []transaction, w io.Writer) error { t := template.New("ledger") _, err := t.Parse(transactionTemplate) if err != nil { return err } t.Execute(w, transactions) return nil } func main() { var config = flag.String("config", "", "configuration file containing all your vendor and account mappings") flag.Parse() filename := flag.Arg(0) r, err := os.Open(filename) if err != nil { log.Fatal(err) } defer r.Close() c, err := os.Open(*config) if err != nil { log.Fatal(err) } defer c.Close() cfg := ini.NewIni() cfg.LoadReader(c) assets, err := cfg.GetSection("Assets") if err != nil { log.Fatal(err) } vendors, err := cfg.GetSection("Vendors") if err != nil { log.Fatal(err) } resp, err := ofxgo.ParseResponse(r) if err != nil { log.Fatal(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() tx := transaction{ Date: t.DtPosted.Time, TrnAmt: t.TrnAmt, Asset: assets.GetValueWithDefault(acctId, acctId), Vendor: matchVendor(vendors.Keys(), t.Name.String()), VendorName: t.Name.String(), } transactions = append(transactions, tx) } } } w := bufio.NewWriter(os.Stdout) sort.Sort(byDate(transactions)) err = generateLedgerTransactions(transactions, w) if err != nil { log.Fatal(err) } err = w.Flush() if err != nil { log.Fatal(err) } }