-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathcontroller.go
226 lines (195 loc) · 6.4 KB
/
controller.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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
package main
import (
"errors"
"github.com/bhutch29/abv/model"
"github.com/bhutch29/abv/undo"
)
// Mode is an Enum of operating modes
type Mode string
// The two main modes: serving and stocking.
const (
serving Mode = "serving"
stocking = "stocking"
)
// ModalController supports using the GUI via distinct behavioral modes
type ModalController struct {
currentMode Mode
backend model.Model
lastBarcode string
lastID string
actor undo.Actor
}
// New creates a new fully initialized ModalController
func New() (ModalController, error) {
m := ModalController{}
m.currentMode = serving
backend, err := model.New()
if err != nil {
return m, err
}
m.backend = backend
a := undo.NewActor()
m.actor = a
return m, nil
}
// GetMode returns the current operating Mode
func (c *ModalController) GetMode() Mode {
return c.currentMode
}
// SetMode changes the current operating Mode
func (c *ModalController) SetMode(m Mode) {
c.currentMode = m
}
// LastBarcode returns the most recently cached barcode
func (c *ModalController) LastBarcode() string {
return c.lastBarcode
}
// LastID returns the most recently cached ID
func (c *ModalController) LastID() string {
return c.lastID
}
// GetInventory returns the currently stocked inventory with default sorting
func (c *ModalController) GetInventory() []model.StockedDrink {
result, err := c.backend.GetInventory()
if err != nil {
logAllError("Error getting current inventory: ", err)
}
return result
}
// GetInventorySorted returns the currently stocked inventory sorted by the provided fields
func (c *ModalController) GetInventorySorted(sortFields []string) []model.StockedDrink {
result, err := c.backend.GetInventorySorted(sortFields)
if err != nil {
logAllError("Error getting current inventory: ", err)
}
return result
}
// NewDrink stores a new drink to the database and increments the drink count
func (c *ModalController) NewDrink(id string, d model.Drink, quantity int) error {
if c.currentMode != stocking {
return errors.New("NewDrink can only be called from stocking mode")
}
logAllDebug("Parsed ID and Barcode:", "ID="+id, ", Barcode="+d.Barcode)
de := model.DrinkEntry{Barcode: d.Barcode, Quantity: quantity}
a := undo.NewCreateAndInputAction(d, de)
if err := c.actor.AddAction(id, a); err != nil {
return err
}
logAllInfo("Drink created and added to inventory!\n #: ", quantity, "\n Name: ", d.Name, "\n Brand: ", d.Brand)
return nil
}
// HandleBarcode inputs/outputs a drink and returns true if the barcode already exists or returns false if the barcode does not exist
func (c *ModalController) HandleBarcode(id string, bc string, quantity int) (bool, error) {
c.lastBarcode = bc
c.lastID = id
exists, err := c.backend.BarcodeExists(bc)
if err != nil {
return false, err
}
if exists {
logFile.Info("Known barcode scanned: ", bc)
c.handleDrink(id, bc, quantity)
return true, nil
}
return false, nil
}
// handleDrink calls either the modal controller's input or output drink
// methods for the given input device and settings, depending on whether
// the current mode is stocking or serving.
func (c *ModalController) handleDrink(id string, bc string, quantity int) {
d := model.DrinkEntry{Barcode: bc, Quantity: quantity}
drink, err := c.backend.GetDrinkByBarcode(d.Barcode)
if err != nil {
logAllError("Error creating drink. Could not get Drink information from barcode: ", err)
}
if c.currentMode == stocking {
c.inputDrinks(id, d, drink)
} else if c.currentMode == serving {
count, err := c.backend.GetCountByBarcode(d.Barcode)
if err != nil {
logAllError("Could not get count by barcode: ", err)
return
}
if count <= 0 {
logAllWarn("That drink was not in the inventory!\n Name: ", drink.Name, "\n Brand: ", drink.Brand)
return
}
c.outputDrinks(id, d, drink)
}
}
// outputDrinks handles the removing of a drink from inventory.
func (c *ModalController) outputDrinks(id string, de model.DrinkEntry, d model.Drink) {
a := undo.NewOutputDrinksAction(de)
logAllDebug("Adding action with id = ", id)
if err := c.actor.AddAction(id, a); err != nil {
logAllError("Could not remove drink from inventory: ", err)
} else {
count, err := c.backend.GetCountByBarcode(d.Barcode)
if err != nil {
logAllError("Could not get count by barcode: ", err)
return
}
logAllInfo("Drink removed from inventory!\n Name: ", d.Name, "\n Brand: ", d.Brand, "\n Remaining: ", count)
}
}
// inputDrinks handles the adding of a drink to inventory.
func (c *ModalController) inputDrinks(id string, de model.DrinkEntry, d model.Drink) {
a := undo.NewInputDrinksAction(de)
logAllDebug("Adding action with id = ", id)
if err := c.actor.AddAction(id, a); err != nil {
logAllError("Could not add drink to inventory: ", err)
} else {
logAllInfo("Drink added to inventory!\n #: ", quantity, "\n Name: ", d.Name, "\n Brand: ", d.Brand)
}
}
// ClearInputOutputRecords wipes out all stocking and serving records
func (c *ModalController) ClearInputOutputRecords() error {
if err := c.backend.ClearInputTable(); err != nil {
return err
}
err := c.backend.ClearOutputTable()
return err
}
// Undo reverts the previous action with the given id, if any
func (c *ModalController) Undo(id string) {
acted, err := c.actor.Undo(id)
if err != nil {
logAllError("Could not undo last action with id = "+id, err)
}
if acted {
logAllInfo("Reverted last action" + c.prettyID(id))
}
}
// Redo reruns the previously reverted action with the given id, if any
func (c *ModalController) Redo(id string) {
acted, err := c.actor.Redo(id)
if err != nil {
logAllError("Could not redo last action with id = "+id, err)
}
if acted {
logAllInfo("Redid last action" + c.prettyID(id))
}
}
// prettyID returns a human readable message with the input device ID.
func (c *ModalController) prettyID(id string) string {
if id == "" {
return ""
}
return " with id = " + id
}
// GetInventoryTotalQuantity returns the total number of beer bottles in stock
func (c *ModalController) GetInventoryTotalQuantity() int {
q, err := c.backend.GetInventoryTotalQuantity()
if err != nil {
logAllError("Could not get total inventory count", err)
}
return q
}
// GetInventoryTotalVariety returns the total number of beer varieties in stock
func (c *ModalController) GetInventoryTotalVariety() int {
q, err := c.backend.GetInventoryTotalVariety()
if err != nil {
logAllError("Could not get total inventory variety count", err)
}
return q
}