From 1d18cb50c5b9b8558e64677f14093b2a595ec476 Mon Sep 17 00:00:00 2001 From: bel Date: Sat, 20 Jul 2024 20:10:35 -0600 Subject: [PATCH] ledger.Transaction.Payee() --- src/ledger/balances.go | 6 +++--- src/ledger/transaction.go | 29 +++++++++++++++++++++++++++++ src/ledger/transaction_test.go | 13 +++++++++++++ 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/src/ledger/balances.go b/src/ledger/balances.go index 89ca093..7d6d519 100644 --- a/src/ledger/balances.go +++ b/src/ledger/balances.go @@ -37,9 +37,9 @@ func (balances Balances) Group(pattern string) Balances { result := make(Balances) p := regexp.MustCompile(pattern) for k, v := range balances { - k2 := p.FindString(k) - if k2 == "" { - k2 = k + k2 := k + if p.MatchString(k) { + k2 = p.FindString(k) } was := result[k2] diff --git a/src/ledger/transaction.go b/src/ledger/transaction.go index 0d67d38..6b382f4 100644 --- a/src/ledger/transaction.go +++ b/src/ledger/transaction.go @@ -39,6 +39,35 @@ func (deltas Deltas) Transactions() Transactions { return result } +func (transaction Transaction) Payee() string { + balances := Deltas(transaction).Balances() + + candidates := []string{} + + for name, balance := range balances { + everyoneElse := balances.NotLike(`^` + name + `$`).Group(`^`)[""] + matches := true + for currency, value := range balance { + matches = matches && everyoneElse[currency]*-1 == value + } + if matches { + candidates = append(candidates, name) + } + } + slices.Sort(candidates) + + if len(candidates) == 0 { + panic(balances) + } + + for _, candidate := range candidates { + if strings.HasPrefix(candidate, "Withdrawal") { + return candidate + } + } + return candidates[len(candidates)-1] +} + type transaction struct { date string description string diff --git a/src/ledger/transaction_test.go b/src/ledger/transaction_test.go index 6ba09ed..69b86c3 100644 --- a/src/ledger/transaction_test.go +++ b/src/ledger/transaction_test.go @@ -8,6 +8,19 @@ import ( "testing" ) +func TestTransactionPayee(t *testing.T) { + given := Transaction{ + Delta{Name: "x", Transaction: "a", Value: 1}, + Delta{Name: "y", Transaction: "a", Value: 2}, + Delta{Name: "Withdrawal:z", Transaction: "a", Value: -3}, + } + + got := given.Payee() + if got != "Withdrawal:z" { + t.Error(got) + } +} + func TestDeltasTransactions(t *testing.T) { given := Deltas{ Delta{Date: "2", Name: "x", Transaction: "a"},