-
Notifications
You must be signed in to change notification settings - Fork 20
/
tickets.go
189 lines (162 loc) · 5.16 KB
/
tickets.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
package flows
import (
"github.com/nyaruka/gocommon/uuids"
"github.com/nyaruka/goflow/assets"
"github.com/nyaruka/goflow/envs"
"github.com/nyaruka/goflow/excellent/types"
)
// TicketUUID is the UUID of a ticket
type TicketUUID uuids.UUID
type baseTicket struct {
UUID TicketUUID `json:"uuid"`
Subject string `json:"subject"`
Body string `json:"body"`
ExternalID string `json:"external_id,omitempty"`
}
// TicketReference is a ticket with a reference to the ticketer
type TicketReference struct {
Ticketer *assets.TicketerReference `json:"ticketer"`
baseTicket
}
// NewTicketReference creates a new ticket with a reference to the ticketer
func NewTicketReference(uuid TicketUUID, ticketer *assets.TicketerReference, subject, body, externalID string) *TicketReference {
return &TicketReference{
baseTicket: baseTicket{
UUID: uuid,
Subject: subject,
Body: body,
ExternalID: externalID,
},
Ticketer: ticketer,
}
}
// Ticket is a ticket in a ticketing system
type Ticket struct {
Ticketer *Ticketer
baseTicket
}
// NewTicket creates a new ticket. Used by ticketing services to open a new ticket.
func NewTicket(ticketer *Ticketer, subject, body string) *Ticket {
return newTicket(TicketUUID(uuids.New()), ticketer, subject, body, "")
}
// creates a new ticket
func newTicket(uuid TicketUUID, ticketer *Ticketer, subject, body, externalID string) *Ticket {
return &Ticket{
baseTicket: baseTicket{
UUID: uuid,
Subject: subject,
Body: body,
ExternalID: externalID,
},
Ticketer: ticketer,
}
}
// Reference converts this ticket to a ticket reference suitable for marshaling
func (t *Ticket) Reference() *TicketReference {
return &TicketReference{
baseTicket: t.baseTicket,
Ticketer: t.Ticketer.Reference(),
}
}
// Context returns the properties available in expressions
//
// uuid:text -> the UUID of the ticket
// subject:text -> the subject of the ticket
// body:text -> the body of the ticket
//
// @context ticket
func (t *Ticket) Context(env envs.Environment) map[string]types.XValue {
return map[string]types.XValue{
"uuid": types.NewXText(string(t.UUID)),
"subject": types.NewXText(t.Subject),
"body": types.NewXText(t.Body),
}
}
// TicketList defines a contact's list of tickets
type TicketList struct {
tickets []*Ticket
}
// NewTicketFromReference creates a new ticket from a ticket reference
func NewTicketFromReference(sa SessionAssets, ref *TicketReference) *Ticket {
ticketer := sa.Ticketers().Get(ref.Ticketer.UUID)
return newTicket(ref.UUID, ticketer, ref.Subject, ref.Body, ref.ExternalID)
}
// NewTicketList creates a new ticket list
func NewTicketList(sa SessionAssets, refs []*TicketReference, missing assets.MissingCallback) *TicketList {
tickets := make([]*Ticket, 0, len(refs))
for _, ref := range refs {
ticket := NewTicketFromReference(sa, ref)
if ticket.Ticketer != nil {
tickets = append(tickets, ticket)
} else {
missing(ref.Ticketer, nil)
}
}
return &TicketList{tickets: tickets}
}
// returns a clone of this ticket list
func (l *TicketList) clone() *TicketList {
tickets := make([]*Ticket, len(l.tickets))
copy(tickets, l.tickets)
return &TicketList{tickets: tickets}
}
// returns this ticket list as a slice of ticket references
func (l *TicketList) references() []*TicketReference {
refs := make([]*TicketReference, len(l.tickets))
for i, ticket := range l.tickets {
refs[i] = ticket.Reference()
}
return refs
}
// Adds adds the given ticket to this ticket list
func (l *TicketList) Add(ticket *Ticket) {
l.tickets = append(l.tickets, ticket)
}
// All returns all tickets in this ticket list
func (l *TicketList) All() []*Ticket {
return l.tickets
}
// Count returns the number of tickets
func (l *TicketList) Count() int {
return len(l.tickets)
}
// ToXValue returns a representation of this object for use in expressions
func (l TicketList) ToXValue(env envs.Environment) types.XValue {
array := make([]types.XValue, len(l.tickets))
for i, ticket := range l.tickets {
array[i] = Context(env, ticket)
}
return types.NewXArray(array...)
}
// Ticketer represents a ticket issuing system.
type Ticketer struct {
assets.Ticketer
}
// NewTicketer returns a new classifier object from the given classifier asset
func NewTicketer(asset assets.Ticketer) *Ticketer {
return &Ticketer{Ticketer: asset}
}
// Asset returns the underlying asset
func (t *Ticketer) Asset() assets.Ticketer { return t.Ticketer }
// Reference returns a reference to this classifier
func (t *Ticketer) Reference() *assets.TicketerReference {
return assets.NewTicketerReference(t.UUID(), t.Name())
}
// TicketerAssets provides access to all ticketer assets
type TicketerAssets struct {
byUUID map[assets.TicketerUUID]*Ticketer
}
// NewTicketerAssets creates a new set of ticketer assets
func NewTicketerAssets(ticketers []assets.Ticketer) *TicketerAssets {
s := &TicketerAssets{
byUUID: make(map[assets.TicketerUUID]*Ticketer, len(ticketers)),
}
for _, asset := range ticketers {
s.byUUID[asset.UUID()] = NewTicketer(asset)
}
return s
}
// Get returns the ticketer with the given UUID
func (s *TicketerAssets) Get(uuid assets.TicketerUUID) *Ticketer {
return s.byUUID[uuid]
}