/
spendings.go
103 lines (90 loc) · 2.9 KB
/
spendings.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package spendings
import (
"github.com/d-ashesss/mah-moneh/internal/accounts"
"github.com/d-ashesss/mah-moneh/internal/categories"
"github.com/d-ashesss/mah-moneh/internal/datastore"
"github.com/d-ashesss/mah-moneh/internal/transactions"
"github.com/gofrs/uuid"
)
// Service categories.
var (
Uncategorized = &categories.Category{
Model: datastore.Model{UUID: uuid.NewV5(uuid.Nil, "Uncategorized")},
}
Unaccounted = &categories.Category{
Model: datastore.Model{UUID: uuid.NewV5(uuid.Nil, "Unaccounted")},
}
)
type Spendings interface {
AddAmount(cat *categories.Category, currency accounts.Currency, amount float64)
AddAmounts(cat *categories.Category, amounts accounts.CurrencyAmounts)
GetAmount(cat *categories.Category, currency accounts.Currency) float64
GetAmounts(cat *categories.Category) accounts.CurrencyAmounts
GetUncategorized() accounts.CurrencyAmounts
GetUnaccounted() accounts.CurrencyAmounts
GetTotal() accounts.CurrencyAmounts
AddTransaction(tx *transactions.Transaction)
}
// spendings contains calculated funds changes for a specific period of time.
type spendings map[uuid.UUID]accounts.CurrencyAmounts
// NewSpendings initializes new spendings structure.
func NewSpendings(cats []*categories.Category) Spendings {
spent := make(spendings)
for _, cat := range cats {
if _, ok := spent[cat.UUID]; !ok {
spent[cat.UUID] = accounts.NewCurrencyAmounts()
}
}
spent[Uncategorized.UUID] = accounts.NewCurrencyAmounts()
spent[Unaccounted.UUID] = accounts.NewCurrencyAmounts()
return spent
}
func (s spendings) AddAmount(cat *categories.Category, currency accounts.Currency, amount float64) {
UUID := uuid.Nil
if cat != nil {
UUID = cat.UUID
}
if _, found := s[UUID]; found {
s[UUID][currency] += amount
} else {
s[Uncategorized.UUID][currency] += amount
}
}
func (s spendings) AddAmounts(cat *categories.Category, amounts accounts.CurrencyAmounts) {
for currency, amount := range amounts {
s.AddAmount(cat, currency, amount)
}
}
func (s spendings) GetAmount(cat *categories.Category, currency accounts.Currency) float64 {
if amounts, found := s[cat.UUID]; found && amounts != nil {
return amounts[currency]
}
return 0
}
func (s spendings) GetAmounts(cat *categories.Category) accounts.CurrencyAmounts {
if amounts, found := s[cat.UUID]; found && amounts != nil {
return amounts
}
return accounts.NewCurrencyAmounts()
}
func (s spendings) AddTransaction(tx *transactions.Transaction) {
s.AddAmount(tx.Category, tx.Currency, tx.Amount)
}
func (s spendings) GetUncategorized() accounts.CurrencyAmounts {
return s[Uncategorized.UUID]
}
func (s spendings) GetUnaccounted() accounts.CurrencyAmounts {
return s[Unaccounted.UUID]
}
func (s spendings) GetTotal() accounts.CurrencyAmounts {
t := accounts.NewCurrencyAmounts()
for UUID, amounts := range s {
if UUID == Unaccounted.UUID {
continue
}
for currency, amount := range amounts {
t[currency] += amount
}
}
return t
}