diff --git a/cmd/cli/main.go b/cmd/cli/main.go index 50d59e0..a7437fe 100644 --- a/cmd/cli/main.go +++ b/cmd/cli/main.go @@ -2,16 +2,22 @@ package cli import ( "bufio" + "context" "flag" "fmt" "io" "math" "os" + "os/signal" "slices" "strings" + "syscall" "time" "gogs.inhome.blapointe.com/ana-ledger/src/ana" + "gogs.inhome.blapointe.com/ana-ledger/src/bank" + "gogs.inhome.blapointe.com/ana-ledger/src/bank/cache" + "gogs.inhome.blapointe.com/ana-ledger/src/bank/teller" "gogs.inhome.blapointe.com/ana-ledger/src/ledger" "github.com/guptarohit/asciigraph" @@ -219,6 +225,60 @@ func Main() { options = append(options, asciigraph.SeriesColors(seriesColors...)) } fmt.Println(asciigraph.PlotMany(points, options...)) + case "rec": + byDate := map[string]ledger.Deltas{} + for _, delta := range deltas { + delta := delta + byDate[delta.Date] = append(byDate[delta.Date], delta) + } + + ctx, can := signal.NotifyContext(context.Background(), syscall.SIGINT) + defer can() + + teller, err := teller.New() + if err != nil { + panic(err) + } + client := cache.New(teller) + + accounts, err := client.Accounts(ctx) + if err != nil { + panic(err) + } + + inDay := func(date string, transaction bank.Transaction) bool { + return slices.ContainsFunc(byDate[date], func(d ledger.Delta) bool { + return d.Value == transaction.Amount + }) + } + + for _, acc := range accounts { + transactions, err := client.Transactions(ctx, acc) + if err != nil { + panic(err) + } + + for _, transaction := range transactions { + if inDay(transaction.Date, transaction) { + continue + } + + err := "missing" + + t, _ := time.ParseInLocation(transaction.Date, "2006-01-02", time.Local) + dayBefore := t.Add(-24 * time.Hour).Format("2006-01-02") + dayAfter := t.Add(-24 * time.Hour).Format("2006-01-02") + if inDay(dayBefore, transaction) || inDay(dayAfter, transaction) { + err = "1dayoff" + } + + prefix := " " + if transaction.Status != "posted" { + prefix = "! " + } + fmt.Printf("[%s] %s $%7.2f %s%s (%s)\n", err, transaction.Date, transaction.Amount, prefix, transaction.Details.CounterParty.Name, transaction.Description) + } + } case "reg": transactions := deltas.Transactions() cumulative := make(ledger.Balances) diff --git a/cmd/cli/run.sh b/cmd/cli/run.sh index 654c27c..3a0718c 100644 --- a/cmd/cli/run.sh +++ b/cmd/cli/run.sh @@ -2,7 +2,7 @@ cmd="bal" case "$1" in - bal|reg|gra|graph ) + bal|reg|gra|graph|rec ) cmd="$1" shift ;; diff --git a/src/bank/types.go b/src/bank/types.go index 45132a5..afc36cc 100644 --- a/src/bank/types.go +++ b/src/bank/types.go @@ -16,7 +16,7 @@ type Account struct { } type Transaction struct { - Amount string `json:"amount"` + Amount float64 `json:"amount,string"` Details struct { ProcessingStatus string `json:"processing_status"` CounterParty struct { @@ -25,6 +25,6 @@ type Transaction struct { } `json:"details"` Description string `json:"description"` Date string `json:"date"` - Type string `json:"fee"` + Type string `json:"type"` Status string `json:"status"` }