diff --git a/cmd/http/public/transactions.html b/cmd/http/public/transactions.html index 4d669eb..a7dd193 100644 --- a/cmd/http/public/transactions.html +++ b/cmd/http/public/transactions.html @@ -47,9 +47,10 @@ } function load(callback) { - http("GET", "/api/transactions" /*?f="+f*/, (body, status) => { + http("GET", "/api/transactions", (body, status) => { var d = JSON.parse(body) console.log("loading", d) + loadNormalized(d.normalized) loadBalances(d.balances) loadTransactions(d.transactions) if (callback != null) { @@ -58,6 +59,17 @@ }) } + function loadNormalized(normalized) { + console.log("loading normalized", normalized) + var result = `` + for (var k in normalized) { + result += `` + } + result += `
${k}${Math.floor(normalized[k]["$"])}
` + document.getElementById("norm").innerHTML = result + } + + function loadBalances(balances) { console.log("loading balances", balances) var result = `` @@ -198,6 +210,10 @@

Moolah2

+ Normalized +
+
+
Balance
diff --git a/cmd/http/router.go b/cmd/http/router.go index 5ddabd3..0828f5b 100644 --- a/cmd/http/router.go +++ b/cmd/http/router.go @@ -6,6 +6,7 @@ import ( "fmt" "io" "io/fs" + "math" "net/http" "os" "slices" @@ -99,17 +100,59 @@ func (router Router) APITransactions(w http.ResponseWriter, r *http.Request) { )) recent := time.Hour * 24 * 365 / 6 - json.NewEncoder(w).Encode(map[string]any{ - "deltas": houseRelatedDeltas. - Like(ledger.LikeAfter(time.Now().Add(-1 * recent).Format("2006-01"))), - "balances": houseRelatedDeltas.Balances(). + normalizer := ana.NewNormalizer(). + With("^Zach:", "2023-10-05", 139). // to turtle + With("^Zach:", "2021-12-30", 135). // at pluralsight + With("^Zach:", "2020-07-30", 120). // to pluralsight + With("^Zach:", "2019-07-16", 77). // at fedex + With("^Zach:", "2017-02-16", 49). // to fedex + With("^Bel:", "2023-12-05", 190). // to render + With("^Bel:", "2022-12-31", 154). // at q + With("^Bel:", "2022-06-30", 148). // at q + With("^Bel:", "2021-12-31", 122). // at q + With("^Bel:", "2020-12-31", 118). // at q + With("^Bel:", "2019-12-31", 111). // at q + With("^Bel:", "2018-12-31", 92). // at q + With("^Bel:", "2018-02-16", 86) // to q + + { + deltas := houseRelatedDeltas. + Like(ledger.LikeAfter(time.Now().Add(-1 * recent).Format("2006-01"))) + + balances := houseRelatedDeltas.Balances(). Like(`^(Zach|Bel|House[^:]*:Debts:)`). Group(`^[^:]*`). - WithBPIs(bpis), - "transactions": houseRelatedDeltas. + WithBPIs(bpis) + + transactions := houseRelatedDeltas. Like(ledger.LikeAfter(time.Now().Add(-1 * recent).Format("2006-01"))). - Transactions(), - }) + Transactions() + + normalized := normalizer.Normalize(houseRelatedDeltas).Balances(). + Like(`^(Zach|Bel):`). + Group(`^[^:]*:`). + WithBPIs(bpis) + var biggest float64 + for _, v := range normalized { + if v := math.Abs(v["$"]); v > biggest { + biggest = v + } + } + for k, v := range normalized { + if v := math.Abs(v["$"]); v < biggest { + normalizedDelta := biggest - v + normalizedFactor := normalizer.NormalizeFactor(ledger.Delta{Name: k, Date: time.Now().Format("2006-01-02")}) + normalized[fmt.Sprintf(`(%s trailing $)`, k)] = ledger.Balance{"$": normalizedDelta * normalizedFactor} + } + } + + json.NewEncoder(w).Encode(map[string]any{ + "deltas": deltas, + "balances": balances, + "normalized": normalized, + "transactions": transactions, + }) + } } func (router Router) APITrends(w http.ResponseWriter, r *http.Request) { diff --git a/src/ana/normalize.go b/src/ana/normalize.go index 256ff9e..42eea75 100644 --- a/src/ana/normalize.go +++ b/src/ana/normalize.go @@ -44,20 +44,26 @@ func (n Normalizer) Normalize(deltas ledger.Deltas) ledger.Deltas { if !like(delta) { continue } - func() { - for pattern := range n.m { - if regexp.MustCompile(pattern).MatchString(delta.Name) { - for _, normalize := range n.m[pattern] { - if normalize.startDate < delta.Date { - delta.Value /= normalize.factor - return - } - } - } - } - }() - deltas[i] = delta + deltas[i] = n.NormalizeDelta(delta) } return deltas } + +func (n Normalizer) NormalizeDelta(delta ledger.Delta) ledger.Delta { + delta.Value /= n.NormalizeFactor(delta) + return delta +} + +func (n Normalizer) NormalizeFactor(delta ledger.Delta) float64 { + for pattern := range n.m { + if regexp.MustCompile(pattern).MatchString(delta.Name) { + for _, normalize := range n.m[pattern] { + if normalize.startDate < delta.Date { + return normalize.factor + } + } + } + } + return 1.0 +}