-
Notifications
You must be signed in to change notification settings - Fork 0
/
interfaces.go
113 lines (95 loc) · 2.26 KB
/
interfaces.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
104
105
106
107
108
109
110
111
112
113
package interest
import (
"github.com/strongo/decimal"
"time"
"fmt"
)
type Credit interface {
Formula() Formula
RatePeriod() RatePeriodInDays
RatePercent() decimal.Decimal64p2
MinimumPeriod() int
GracePeriod() int
}
type Deal interface {
Credit
Time() time.Time
LentAmount() decimal.Decimal64p2
}
type deal struct {
formula Formula
time time.Time
lentAmount decimal.Decimal64p2
ratePeriod RatePeriodInDays
ratePercent decimal.Decimal64p2
minimumPeriod int
gracePeriod int
}
func (d deal) Formula() Formula {
return d.formula
}
func (d deal) LentAmount() decimal.Decimal64p2 {
return d.lentAmount
}
func (d deal) RatePercent() decimal.Decimal64p2 {
return d.ratePercent
}
func (d deal) RatePeriod() RatePeriodInDays {
return d.ratePeriod
}
func (d deal) MinimumPeriod() int {
return d.minimumPeriod
}
func (d deal) GracePeriod() int {
return d.gracePeriod
}
func (d deal) Time() time.Time {
return d.time
}
func NewDeal(formula Formula, time time.Time, lentAmount, ratePercent decimal.Decimal64p2, ratePeriod RatePeriodInDays, minimumPeriod, gracePeriod int) Deal {
if lentAmount < 0 {
panic(fmt.Sprintf("lentAmount <= 0: %v", lentAmount))
}
if ratePercent < 0 {
panic(fmt.Sprintf("ratePercent <= 0: %v", ratePercent))
}
if minimumPeriod < 0 {
panic(fmt.Sprintf("minimumPeriod <= 0: %v", minimumPeriod))
}
if gracePeriod < 0 {
panic(fmt.Sprintf("gracePeriod <= 0: %v", gracePeriod))
}
if ratePeriod <= 0 {
panic(fmt.Sprintf("ratePeriod <= 0: %v", ratePeriod))
}
return deal{
formula: formula,
time: time,
lentAmount: lentAmount,
ratePeriod: ratePeriod,
ratePercent: ratePercent,
minimumPeriod: minimumPeriod,
gracePeriod: gracePeriod,
}
}
type Payment interface {
Time() time.Time
Amount() decimal.Decimal64p2
}
type payment struct {
time time.Time
amount decimal.Decimal64p2
}
func (p payment) Time() time.Time {
return p.time
}
func (p payment) Amount() decimal.Decimal64p2 {
return p.amount
}
func NewPayment(time time.Time, amount decimal.Decimal64p2) Payment {
return payment{time: time, amount: amount}
}
type Calculator interface {
Formula() Formula
Calculate(reportTime time.Time, deal Deal, payments []Payment) (interest, outstanding decimal.Decimal64p2, err error)
}