src/app/models.go (view raw)
1package app
2
3import (
4 "log"
5 "time"
6)
7
8type Bookmaker struct {
9 ID uint `json:"id"`
10 CreatedAt time.Time `json:"created_at"`
11 UpdatedAt time.Time `json:"updated_at"`
12
13 Name string `json:"name" gorm:"not null" `
14 Exchange bool `json:"exchange" gorm:"not null" `
15 DefaultCommission uint `json:"default_commission" gorm:"not null"`
16}
17
18type Account struct {
19 ID uint `json:"id"`
20 CreatedAt time.Time `json:"created_at"`
21
22 Name string `json:"name" gorm:"not null"`
23}
24
25type Record struct {
26 ID uint `json:"id" gorm:"primaryKey"`
27 CreatedAt time.Time `json:"created_at"`
28 UpdatedAt time.Time `json:"updated_at"`
29
30 Done bool `json:"done" gorm:"not null"`
31 Type string `json:"type" gorm:"not null"`
32 Description string `json:"description" gorm:"not null"`
33
34 Date *time.Time `json:"date" gorm:"-"`
35 Value *int `json:"value" gorm:"-"`
36
37 Entries []Entry `json:"entries" gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
38}
39
40type Entry struct {
41 ID uint `json:"id"`
42 CreatedAt time.Time `json:"created_at"`
43 UpdatedAt time.Time `json:"updated_at"`
44
45 RecordID uint `json:"record_id" gorm:"not null"`
46 BookmakerID uint `json:"bookmaker_id" gorm:"not null"`
47 AccountID uint `json:"account_id" gorm:"not null"`
48 Amount uint `json:"amount" gorm:"not null"` // In cents (ex: 100 = 1.00)
49 Refund uint `json:"refund" gorm:"not null"` // In cents (ex: 100 = 1.00)
50 Bonus uint `json:"bonus" gorm:"not null"` // In cents (ex: 50 = 0.50)
51 Commission uint `json:"commission" gorm:"not null"` // In cents (ex: 4.5% = 450)
52
53 Odds *uint `json:"odds" gorm:"-"`
54 Won *bool `json:"won" gorm:"-"`
55 Date *time.Time `json:"date" gorm:"-"`
56 Value *int `json:"value" gorm:"-"`
57
58 SubEntries []SubEntry `json:"sub_entries" gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
59}
60
61type SubEntry struct {
62 ID uint `json:"id"`
63 CreatedAt time.Time `json:"created_at"`
64 UpdatedAt time.Time `json:"updated_at"`
65
66 EntryID uint `json:"entry_id" gorm:"not null"`
67 Description string `json:"description" gorm:"not null"`
68 Odds uint `json:"odds" gorm:"not null"` // In cents (ex: 200 = 2.00)
69 Won bool `json:"won" gorm:"not null"`
70 Date time.Time `json:"date" gorm:"not null;default:current_timestamp"`
71
72 Value *int `json:"value" gorm:"-"`
73}
74
75func (e *Entry) GetOdds() *uint {
76 v := uint(1)
77 for _, s := range e.SubEntries {
78 v *= s.Odds
79 }
80 return &v
81}
82
83func (e *Entry) DidWin() *bool {
84 v := true
85 for _, s := range e.SubEntries {
86 if !s.Won {
87 v = false
88 return &v
89 }
90 }
91 return &v
92}
93
94func (e *Entry) GetDate() *time.Time {
95 if len(e.SubEntries) == 0 {
96 return nil
97 }
98
99 last := e.SubEntries[0].Date
100 for _, s := range e.SubEntries {
101 if s.Date.After(last) {
102 last = s.Date
103 }
104 }
105 return &last
106}
107
108func (e *Entry) GetValue() (value int) {
109 if e.Won == nil || e.Odds == nil {
110 log.Fatalf("please, update e.Won and e.Odds first")
111 }
112
113 if IsExchange(e.BookmakerID) {
114 r := (int(e.Amount) * (int(*e.Odds) - 100)) / 100
115 if *e.Won {
116 value = int(e.Amount) - int(e.Amount)*int(e.Commission)/10000
117 } else {
118 value = int(e.Refund) - r
119 }
120 } else {
121 if *e.Won {
122 value = (int(e.Amount) * int(*e.Odds) / 100) - int(e.Amount)
123 } else {
124 value = -int(e.Amount) + int(e.Refund)
125 }
126 }
127
128 value += int(e.Bonus)
129 return
130}
131
132func (r *Record) GetDate() *time.Time {
133 if len(r.Entries) == 0 {
134 return nil
135 }
136
137 last := *r.Entries[0].Date
138 for _, e := range r.Entries {
139 if e.Date.After(last) {
140 last = *e.Date
141 }
142 }
143 return &last
144}
145
146func FillEntryValues(entries []Entry) ([]Entry, int) {
147 var total int
148 for i := range entries {
149 entries[i].Odds = entries[i].GetOdds()
150 entries[i].Won = entries[i].DidWin()
151 entries[i].Date = entries[i].GetDate()
152 v := entries[i].GetValue()
153 entries[i].Value = &v
154 total += v
155 }
156 return entries, total
157}
158
159func FillRecordValues(records []Record) ([]Record, int) {
160 var total int
161 for i := range records {
162 _, v := FillEntryValues(records[i].Entries)
163 records[i].Date = records[i].GetDate()
164 records[i].Value = &v
165 total += v
166 }
167 return records, total
168}
169
170func GetRecords() (records []Record, total int, err error) {
171 err = DB.Preload("Entries.SubEntries").Find(&records).Error
172 if err != nil {
173 return
174 }
175
176 records, total = FillRecordValues(records)
177 return
178}