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
|
- I have a MonitoredQueue that sets tickets to "Monitored"
if its subject matches /monitored/.
- I want to have a kind of Ticket that are 'Monitored'.
- I want all monitored tickets, when they are overdue for
14 days, to:
- send notification to manager
- mark as stalled
- I want all monitored tickets, when they are overdue for
28 days, to:
- mark as rejected
- I want to query all tickets that are monitored as such
- I want to modify 14 => 15 and have it affect all existing
tickets that are monitored
{
- I want to add a new "overdue for 27 days, add a 'ultimatum'
correspondence to it" rule for all monitored tickets.
- I want to add a new "overdue for 27 days, add a 'ultimatum'
correspondence to it" rule for all _new_ monitored tickets
without affecting existing ones.
}
- The user of OrderRequest queue needs to fill a numeric "CF",
called "Price".
- On creation, it needs to create following approvals:
- "Manager" approval if CF.Price is > 1000
- "President" approval if CF.Price is > 2000
- When all of "M", "P" are resolved (if any, or if there were none
to begin with), Create a new approval, "Finance".
- If any approvals above is rejected, reject the original ticket.
- If "Finance" is resolved, resolve original ticket.
- If "Finance" is rejected, create an approval for "CEO".
- If "CEO" is resolved, resolve the original ticket.
- If "CEO" is rejected, reject the original ticket.
[RuleAction CreateTicketWithRuleset]
-> ReleaseMyLockOnRuleset $ruleset
-> UnlessLockOnRuleset $ruleset
# i.e. if no active tickets still have a lock on it
-> ForceCreateTicketWithRuleset $ruleset
[Queue OrderRequest]
-> Condition: OnCreate
Action: AddTicketRuleSet "PurchaseApproval"
# Triggers immediately
[RuleSet: PurchaseApproval]
-> Condition: OnCreate
Condition: CF.Price > 1000
Action: CreateTicketWithRuleset "ManagerApproval"
-> Condition: OnCreate
Condition: CF.Price > 2000
Action: CreateTicketWithRuleset "PresidentApproval"
-> Condition: OnCreate
Action: CreateTicketWithRuleset "FinanceApproval"
-> Condition: OnReject
Action: DeleteTree
[RuleSet: ManagerApproval]
-> Condition: OnCreate
Action: Prohibit Ruleset "FinanceApproval"
-> Condition: OnResolve
Action: CreateTicketWithRuleset "FinanceApproval"
-> Condition: OnReject
Action: RejectTicket TOP
[RuleSet: PresidentApproval]
-> Condition: OnCreate
Action: Prohibit CreateTicketWithRuleset "FinanceApproval"
-> Condition: OnResolve
Action: CreateTicketWithRuleset "FinanceApproval"
-> Condition: OnReject
Action: RejectTicket TOP
[RuleSet: FinanceApproval]
-> Condition: OnCreate
Action: Prohibit RuleSet "CEOApproval"
-> Condition: OnResolve
Action: ResolveTicket TOP
-> Condition: OnReject
Action: CreateTicketWithRuleset "CEOApproval"
[RuleSet: CEOApproval]
-> Condition: OnResolve
Action: ResolveTicket TOP
-> Condition: OnReject
Action: RejectTicket TOP
Prohibit Ticket Operation:
Ruleset CEOApproval
,--------.
[TOP] --> [M] --> [F]
` `-> [P] -'
`
`-> [X] --> [Y]
[TOP] => [Approval]
-> Queue: B
-> Rule: yyy
-> Workflow: W
-> Stage: Approval
-> Rule: xxx
isa_ok( $Approval->Type, 'RT::Ticket' );
is( $Approval->Workflow->Name, 'W' );
is( $Approval->Stage->Name, 'Approval' );
[Queue: A]
-> Workflow: W
[Workflow: W]
-> Stage: TOP
-> Stage: Approval
-> Stage: SUCCESS
-> Stage: FAIL
"RuleCollections"
[Stage: TOP]
-> Rule: OnCreate RunStage Approval
ok( TicketA->Rules->HasEntry($ApprovalRule) )
ok( TicketB->Rules->HasEntry($ApprovalRule) )
[Rule: Approval]
-> Rule: OnResolve RunStage SUCCESS
-> Rule: OnReject RunStage FAIL
[Stage: SUCCESS]
-> Rule: OnCreate SetStatus('resolved') TOP
[Stage: FAIL]
-> Rule: OnCreate SetStatus('rejected') TOP
[Unassociated]
- Rule FOO: OnAnything {
CreateTicketIfNotBlocked StageFOO
AddLink DependedOnBy TOP to Stage1
AssignRule DoStage2 to Stage1
AssignRule DoStage3 to Stage1
}
- Rule BAR: OnAnything {
CreateTicketIfNotBlocked StageBAR
DoSomethingBizzare
}
,==> [Stage0] ==>.
, .
[TOP] ==> [Stage1] ==> [Stage3]
` '
`==> [Stage2] ==>'
OnTransaction:
$self->Ticket->Queues->Scrips->Apply
OnTransaction:
$self->Ticket->Queues->Scrips->Apply
->Scrips->Apply
OnTransaction:
$self->Ticket->Queues->Scrips->Apply
->Stages->Scrips->Apply
[QueueX]
- Rule:
OnCreate:
RunRule FOO
[QueueY]
- Rule:
OnWhatever:
RunRule FOO
[TOP] => [Stage1] => [Stage2] => [END]
`- => [Stage3] => [END]
` -> [Stage4]
[Stages]
->
|