-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathuser.go
118 lines (102 loc) · 3.22 KB
/
user.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
package aumo
import (
"strings"
"github.com/google/uuid"
"golang.org/x/crypto/bcrypt"
"upper.io/db.v3/lib/sqlbuilder"
)
const (
// UserStartingPoints is the starting points of a user
UserStartingPoints = float64(5000)
// UserPointsPerReceipt is the amount of points a user gets per receipt claimed
UserPointsPerReceipt = float64(500)
)
// User represents a user of aumo
type User struct {
ID uuid.UUID `json:"id,omitempty" db:"id,omitempty"`
Name string `json:"name" db:"name"`
Email string `json:"email" db:"email"`
Password string `json:"-" db:"password"`
Avatar string `json:"avatar" db:"avatar"`
Points float64 `json:"points" db:"points"`
Role Role `json:"role" db:"role"`
Orders []Order `json:"orders" db:"-"`
Receipts []Receipt `json:"receipts" db:"-"`
IsVerified bool `json:"is_verified" db:"verified"`
Shops []Shop `json:"shops,omitempty" db:"-"`
}
// ClaimReceipt claims a receipt and adds it to the receipts array
func (u *User) ClaimReceipt(r *Receipt) {
u.Receipts = append(u.Receipts, *r)
}
// ValidatePassword checks if the passed password is the correct one
func (u *User) ValidatePassword(password string) bool {
if err := bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(password)); err == nil {
return true
}
return false
}
// PlaceOrder adds the passed Product to the user's inventory
// if they have enough money to buy the desired quantity;
// subtracts points from the user
func (u *User) PlaceOrder(o *Order) error {
p := o.Product
// Check if the user has enough points
if u.Points-p.Price < 0 {
return ErrNotSufficientPoints
}
// Check if there is enough in stock
if p.Stock < 1 {
return ErrNotInStock
}
// Subtract the points of the user
u.Points -= p.Price
// Add the item to the orders array
u.Orders = append(u.Orders, *o)
return nil
}
// NewUser is a constructor for `User`
func NewUser(name string, email string, password string, avatar string) (*User, error) {
pwd, err := bcrypt.GenerateFromPassword([]byte(password), 12)
if err != nil {
return nil, err
}
return &User{
ID: uuid.New(),
Name: name,
Email: strings.ToLower(strings.Trim(email, " ")),
Password: string(pwd),
Avatar: avatar,
Points: UserStartingPoints,
Role: Customer,
Orders: []Order{},
Receipts: []Receipt{},
Shops: []Shop{},
IsVerified: false,
}, nil
}
// UserService contains all `User`
// related business logic
type UserService interface {
User(id string, relations bool) (*User, error)
UserByEmail(email string, relations bool) (*User, error)
Users() ([]User, error)
Create(*User) error
Update(id string, u *User) error
EditRole(id string, role Role) error
AddPoints(id string, points float64) error
SubPoints(id string, points float64) error
Verify(id string) error
Delete(id string) error
}
// UserStore contains all `User`
// related persistence logic
type UserStore interface {
DB() sqlbuilder.Database
FindByID(tx Tx, id string, relations bool) (*User, error)
FindByEmail(tx Tx, email string, relations bool) (*User, error)
FindAll(tx Tx) ([]User, error)
Save(tx Tx, u *User) error
Update(tx Tx, id string, u *User) error
Delete(tx Tx, id string) error
}