65 lines
1.1 KiB
Go
65 lines
1.1 KiB
Go
package ledger
|
|
|
|
import (
|
|
"bufio"
|
|
"bytes"
|
|
"io"
|
|
"os"
|
|
"strconv"
|
|
)
|
|
|
|
type BPIs map[Currency]BPI
|
|
|
|
type BPI map[string]float64
|
|
|
|
func NewBPIs(p string) (BPIs, error) {
|
|
f, err := os.Open(p)
|
|
if os.IsNotExist(err) {
|
|
return nil, nil
|
|
}
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer f.Close()
|
|
|
|
result := make(map[Currency]BPI)
|
|
|
|
r := bufio.NewReader(f)
|
|
for {
|
|
line, err := readTransactionLine(r)
|
|
if len(line) > 0 {
|
|
fields := bytes.Fields(line)
|
|
if len(fields) > 3 {
|
|
date := string(fields[1])
|
|
currency := Currency(fields[len(fields)-2])
|
|
value, err := strconv.ParseFloat(string(fields[len(fields)-1][1:]), 64)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if _, ok := result[currency]; !ok {
|
|
result[currency] = make(BPI)
|
|
}
|
|
result[currency][date] = value
|
|
}
|
|
}
|
|
if err == io.EOF {
|
|
return result, nil
|
|
} else if err != nil {
|
|
return result, err
|
|
}
|
|
}
|
|
}
|
|
|
|
func (bpi BPI) Lookup(date string) float64 {
|
|
var closestWithoutGoingOver string
|
|
for k := range bpi {
|
|
if k <= date && k > closestWithoutGoingOver {
|
|
closestWithoutGoingOver = k
|
|
}
|
|
}
|
|
if closestWithoutGoingOver == "" {
|
|
return 0
|
|
}
|
|
return bpi[closestWithoutGoingOver]
|
|
}
|