Skip to content

Commit

Permalink
Move all logic into processors
Browse files Browse the repository at this point in the history
  • Loading branch information
Silvio Böhler committed Nov 21, 2021
1 parent 701e76b commit 5b8d249
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 40 deletions.
62 changes: 38 additions & 24 deletions lib/balance/balance.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
package balance

import (
"bytes"
"fmt"
"strings"
"time"

"github.com/sboehler/knut/lib/date"
Expand Down Expand Up @@ -103,8 +103,6 @@ func (b *Balance) bookValue(t ledger.Transaction) error {
return nil
}

// Options has options for processing a ledger

// Diffs creates the difference balances for the given
// slice of balances. The returned slice is one element smaller
// than the input slice. The balances are mutated.
Expand All @@ -124,7 +122,7 @@ type Error struct {
func (be Error) Error() string {
var (
p printer.Printer
b bytes.Buffer
b strings.Builder
)
fmt.Fprintf(&b, "%s:\n", be.directive.Position().Start)
p.PrintDirective(&b, be.directive)
Expand Down Expand Up @@ -160,32 +158,48 @@ type Builder struct {

// Build builds a sequence of balances.
func (b Builder) Build(l ledger.Ledger) ([]*Balance, error) {
var result []*Balance
var ppl = []Processor{
DateUpdater{},
&Snapshotter{Dates: l.Dates(b.From, b.To, b.Period), Result: &result},
PriceUpdater{pr: make(prices.Prices)},
AccountOpener{},
TransactionBooker{},
ValueBooker{},
Asserter{},
TransactionValuator{},
ValuationTransactionComputer{},
AccountCloser{},
}
var bal = New(l.Context, b.Valuation)
var (
result []*Balance
processors = []Processor{
DateUpdater{},
&Snapshotter{
From: b.From,
To: b.To,
Period: b.Period,
Last: b.Last,
Diff: b.Diff,
Result: &result},
AccountOpener{},
TransactionBooker{},
ValueBooker{},
Asserter{},
new(PriceUpdater),
TransactionValuator{},
ValuationTransactionComputer{},
AccountCloser{},
}
bal = New(l.Context, b.Valuation)
)
for _, pr := range processors {
if f, ok := pr.(Initializer); ok {
if err := f.Initialize(l); err != nil {
return nil, err
}
}
}
for _, step := range l.Days {
for _, pr := range ppl {
for _, pr := range processors {
if err := pr.Process(bal, step); err != nil {
return nil, err
}
}
}
if b.Diff {
result = Diffs(result)
}
if b.Last > 0 && b.Last < len(result) {
result = result[len(result)-b.Last:]
for _, pr := range processors {
if f, ok := pr.(Finalizer); ok {
if err := f.Finalize(bal); err != nil {
return nil, err
}
}
}
return result, nil
}
Expand Down
79 changes: 63 additions & 16 deletions lib/balance/processors.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,26 @@ import (
"sort"
"time"

"github.com/sboehler/knut/lib/date"
"github.com/sboehler/knut/lib/ledger"
"github.com/sboehler/knut/lib/prices"
)

// Initializer gets called before processing.
type Initializer interface {
Initialize(l ledger.Ledger) error
}

// Processor processes the balance and the ledger day.
type Processor interface {
Process(b *Balance, d *ledger.Day) error
}

// Finalizer gets called after all days have been processed.
type Finalizer interface {
Finalize(b *Balance) error
}

// DateUpdater keeps track of open accounts.
type DateUpdater struct{}

Expand All @@ -27,30 +38,57 @@ func (a DateUpdater) Process(b *Balance, d *ledger.Day) error {

// Snapshotter keeps track of open accounts.
type Snapshotter struct {
Result *[]*Balance
Dates []time.Time
index int
From, To *time.Time
Last int
Diff bool
Period *date.Period
Result *[]*Balance
dates []time.Time
index int
}

var _ Processor = (*Snapshotter)(nil)
var (
_ Initializer = (*Snapshotter)(nil)
_ Processor = (*Snapshotter)(nil)
_ Finalizer = (*Snapshotter)(nil)
)

// Initialize implements Initializer.
func (a *Snapshotter) Initialize(l ledger.Ledger) error {
a.dates = l.Dates(a.From, a.To, a.Period)
var offset = 0
if a.Diff {
offset = 1
}
if a.Last > 0 && a.Last < len(a.dates)-offset {
a.dates = a.dates[len(a.dates)-a.Last-offset:]
}
*a.Result = make([]*Balance, len(a.dates))
return nil
}

// Process implements Processor.
func (a *Snapshotter) Process(b *Balance, d *ledger.Day) error {
if len(a.Dates) == 0 || a.index >= len(a.Dates) {
if len(a.dates) == 0 || a.index >= len(a.dates) {
return nil
}
if len(*a.Result) == 0 {
*a.Result = make([]*Balance, len(a.Dates))
(*a.Result)[0] = b
for ; a.index < len(a.dates) && d.Date.After(a.dates[a.index]); a.index++ {
var cp = b.Copy()
cp.Date = a.dates[a.index]
(*a.Result)[a.index] = cp
}
for d.Date.After(a.Dates[a.index]) && (*a.Result)[a.index] == b {
return nil
}

// Finalize implements Finalizer.
func (a *Snapshotter) Finalize(b *Balance) error {
for ; a.index < len(a.dates); a.index++ {
var cp = b.Copy()
cp.Date = a.Dates[a.index]
cp.Date = a.dates[a.index]
(*a.Result)[a.index] = cp
if a.index < len(a.Dates)-1 {
a.index++
(*a.Result)[a.index] = b
}
}
if a.Diff {
*a.Result = Diffs(*a.Result)
}
return nil
}
Expand All @@ -60,10 +98,19 @@ type PriceUpdater struct {
pr prices.Prices
}

var _ Processor = (*PriceUpdater)(nil)
var (
_ Initializer = (*PriceUpdater)(nil)
_ Processor = (*PriceUpdater)(nil)
)

// Initialize implements Initializer.
func (a *PriceUpdater) Initialize(_ ledger.Ledger) error {
a.pr = make(prices.Prices)
return nil
}

// Process implements Processor.
func (a PriceUpdater) Process(b *Balance, d *ledger.Day) error {
func (a *PriceUpdater) Process(b *Balance, d *ledger.Day) error {
if b.Valuation == nil {
return nil
}
Expand Down

0 comments on commit 5b8d249

Please sign in to comment.