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 += `| ${k} | ${Math.floor(normalized[k]["$"])} |
`
+ }
+ result += `
`
+ 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
+}