forked from joshsoftware/curem
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlead.go
174 lines (158 loc) · 5.1 KB
/
lead.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
package main
import (
"errors"
"fmt"
"strings"
"time"
"github.com/joshsoftware/curem/config"
"labix.org/v2/mgo/bson"
)
var statusOptions = []string{"Won", "Lost", "Warming Up", "Cooling Down", "Tech", "Negotiating", "Proposal", "Contract"}
type lead struct {
ID bson.ObjectId `bson:"_id" json:"id"`
ContactID bson.ObjectId `bson:"contactID,omitempty" json:"contactID,omitempty"`
Source string `bson:"source,omitempty" json:"source,omitempty"`
Owner string `bson:"owner,omitempty" json:"owner,omitempty"`
Status string `bson:"status,omitempty" json:"status,omitempty"`
TeamSize float64 `bson:"teamSize,omitempty" json:"teamSize,omitempty"`
RatePerHour float64 `bson:"ratePerHour,omitempty" json:"ratePerHour,omitempty"`
DurationInMonths float64 `bson:"durationInMonths,omitempty" json:"durationInMonths,omitempty"`
EstimatedStartDate string `bson:"estimatedStartDate,omitempty" json:"estimatedStartDate,omitempty"`
Comments []string `bson:"comments,omitempty" json:"comments,omitempty"`
CreatedAt time.Time `bson:"createdAt,omitempty" json:"createdAt,omitempty"`
UpdatedAt time.Time `bson:"updatedAt,omitempty" json:"updatedAt,omitempty"`
}
type incomingLead struct {
ID *bson.ObjectId `json:"id"`
ContactID *bson.ObjectId `json:"contactID,omitempty"`
Source *string `json:"source,omitempty"`
Owner *string `json:"owner,omitempty"`
Status *string `json:"status,omitempty"`
TeamSize *float64 `json:"teamSize,omitempty"`
RatePerHour *float64 `json:"ratePerHour,omitempty"`
DurationInMonths *float64 `json:"durationInMonths,omitempty"`
EstimatedStartDate *string `json:"estimatedStartDate,omitempty"`
Comments *[]string `json:"comments,omitempty"`
}
func (l *lead) copyIncomingFields(i *incomingLead) error {
if i.ID != nil {
if *i.ID != l.ID {
return errors.New("id doesn't match")
}
}
if i.ContactID != nil {
l.ID = *i.ID
}
if i.Source != nil {
l.Source = *i.Source
}
if i.Owner != nil {
l.Owner = *i.Owner
}
if i.Status != nil {
l.Status = *i.Status
}
if i.TeamSize != nil {
l.TeamSize = *i.TeamSize
}
if i.RatePerHour != nil {
l.RatePerHour = *i.RatePerHour
}
if i.DurationInMonths != nil {
l.DurationInMonths = *i.DurationInMonths
}
if i.EstimatedStartDate != nil {
l.EstimatedStartDate = *i.EstimatedStartDate
}
if i.Comments != nil {
l.Comments = *i.Comments
}
return nil
}
func (l *lead) Validate() error {
if l.ContactID == "" {
return errors.New("contact ID can't be empty")
}
if l.Source == "" {
return errors.New("source can't be empty")
}
if l.Owner == "" {
return errors.New("owner can't be empty")
}
if l.Status == "" {
return errors.New("status can't be empty")
}
if !isStatusValid(l.Status) {
return fmt.Errorf("status is invalid. Can only be one of %s", statusOptions)
}
return nil
}
func isStatusValid(s string) bool {
for _, v := range statusOptions {
if v == s {
return true
}
}
return false
}
// NewLead takes the fields of a lead, initializes a struct of lead type and returns
// the pointer to that struct.
// Also, It inserts the lead object into the database.
func NewLead(cid bson.ObjectId, source, owner, status string, teamsize, rate, duration float64,
start string, comments []string) (*lead, error) {
doc := lead{
ID: bson.NewObjectId(),
ContactID: cid,
Source: strings.Title(source),
Owner: strings.Title(owner),
Status: strings.Title(status),
TeamSize: teamsize,
RatePerHour: rate,
DurationInMonths: duration,
EstimatedStartDate: start,
Comments: comments,
}
if err := (&doc).Validate(); err != nil {
return &lead{}, err
}
doc.CreatedAt = doc.ID.Time()
doc.UpdatedAt = doc.CreatedAt
err := config.LeadsCollection.Insert(doc)
if err != nil {
return &lead{}, err
}
return &doc, nil
}
// GetLead takes the lead ID as an argument and returns a pointer to a lead object.
func GetLead(i bson.ObjectId) (*lead, error) {
var l lead
err := config.LeadsCollection.FindId(i).One(&l)
if err != nil {
return &lead{}, err
}
return &l, nil
}
// GetAllLeads fetches all the leads from the database.
func GetAllLeads() ([]lead, error) {
var l []lead
err := config.LeadsCollection.Find(nil).All(&l)
if err != nil {
return []lead{}, err
}
return l, nil
}
// Update updates the lead in the database.
// First, fetch a lead from the database and change the necessary fields.
// Then call the Update method on that lead object.
func (l *lead) Update() error {
if err := l.Validate(); err != nil {
return err
}
l.UpdatedAt = bson.Now()
err := config.LeadsCollection.UpdateId(l.ID, l)
return err
}
// Delete deletes the lead from the database.
func (l *lead) Delete() error {
return config.LeadsCollection.RemoveId(l.ID)
}