automate setup of custom field, #34061
[freeside.git] / rt / share / html / Admin / Queues / Tasks.html
1 <& /Admin/Elements/Header, Title => $title &>
2 <& /Elements/Tabs &>
3 <& /Elements/ListActions, actions => \@results &>
4
5 <form action="Tasks.html" method="post">
6 <input type="hidden" name="Queue" value="<% $Queue %>" />
7 <table>
8 % my (@links, @postponed); # not really used here
9 % my $idx = 1;
10 % foreach my $task_id (@task_ids, 'new') {
11 %   # simulate creating the tickets, but don't evaluate any perl inclusions
12 %   # in the content (_ActiveContent => 0 earlier)
13 %   my ($ticket, $ticketargs);
14 %   if ( $task_id eq 'new' ) {
15 %     $ticket = RT::Ticket->new($session{'CurrentUser'});
16 %     $ticketargs = {
17 %       Queue => $Queue,
18 %       # any other defaults make sense here?
19 %     };
20 %   } else {
21 %     ($ticket, $ticketargs) =
22 %       $Action->ParseLines($task_id, \@links, \@postponed);
23 %   }
24 %   my $subject = $ticketargs->{Subject};
25 %   my $subjectprefix = 0;
26 %   if ( $subject =~ s/^\Q$SUBJECT_PREFIX\E// ) {
27 %     $subjectprefix = 1;
28 %   }
29
30   <tr>
31     <td colspan="2">
32       <h2>
33       <label for="task_id"><&|/l&>Task #</&><% $idx %>
34 % # each time these are edited, replace all task IDs with sequential numbers.
35 % # no point in letting them be anything else, at least yet.
36       <input type="hidden" name="task_id" value="<% $idx %>">
37       </h2>
38     </td>
39   </tr>
40   <tr>
41     <td class="label"><&|/l&>Subject</&>:</td>
42     <td class="value">
43       <input name="<% $idx %>-Subject" value="<% $subject |h %>" />
44       <input type="checkbox" name="<% $idx %>-SubjectPrefix" <% $subjectprefix ? 'checked' : '' %> /> <&|/l&>Prefix with main subject</&>
45     </td>
46   </tr>
47   <tr>
48     <td class="label"><&|/l&>In queue</&>:</td>
49     <td class="value"><& /Elements/SelectQueue,
50       Name => "$idx-Queue",
51       ShowNullOption => 0,
52       Default => ($ticketargs->{Queue} || $Queue),
53     &></td>
54   </tr>
55   <tr>
56     <td class="label"><&|/l&>Content</&>:</td>
57     <td class="value"><textarea name="<% $idx %>-Content" rows="10" cols="80" wrap="soft"><%
58     ( $ticketargs->{MIMEObj} ? $ticketargs->{MIMEObj}->body_as_string : '' )
59     %></textarea>
60     </td>
61   </tr>
62
63 %   $idx++;
64 % }
65 </table>
66 <& /Elements/Submit, Label => 'Save Changes' &>
67 </form>
68 <%init>
69 my @results;
70
71 my $QueueObj = RT::Queue->new($session{'CurrentUser'});
72 $QueueObj->Load($Queue);
73 Abort(loc("Queue [_1] not found",$Queue)) unless $QueueObj->Id;
74
75 my $title = loc("Set up subtasks for queue [_1]", $QueueObj->Name);
76
77 my $TEMPLATE_NAME = '[Subtask]';
78 my $SCRIPCONDITION_NAME = '[Subtask] Queue='.$Queue;
79 my $SUBJECT_PREFIX = q({ $TOP->Subject }-);
80 my $CUSTOMFIELD_NAME = 'Create subtasks';
81
82 my ($Scrip, $ScripCondition, $Template, $CustomField);
83
84 # SystemUser for the scrip so that the user doesn't need ACLs to edit scrips
85 # as such.  all the scrip parameters are hardcoded anyway...
86
87 $ScripCondition = RT::ScripCondition->new($RT::SystemUser);
88 $ScripCondition->LoadByCol('Name', $SCRIPCONDITION_NAME);
89
90 $Template = RT::Template->new($session{'CurrentUser'});
91 $Template->LoadByName(
92   Name  => $TEMPLATE_NAME,
93   Queue => $Queue,
94 );
95
96 $Scrip = RT::Scrip->new($RT::SystemUser);
97 {
98   my $Scrips = RT::Scrips->new($RT::SystemUser);
99   $Scrips->LimitToQueue($Queue);
100   $Scrips->Limit( FIELD => 'Template', VALUE => $Template->Id );
101   if ( $Scrips->Count > 0 ) {
102     $Scrip = $Scrips->First;
103   }
104 }
105
106 my $CustomField = RT::CustomField->new($RT::SystemUser);
107 $CustomField->LoadByName(
108   Name        => $CUSTOMFIELD_NAME,
109   LookupType  => 'RT::Queue-RT::Ticket',
110 );
111
112 # if there's input from the form, process it into a new template content
113 my $new_content = '';
114
115 if ( $ARGS{task_id} ) { # actually contains numeric indices
116   my @task_ids = $ARGS{task_id};
117   @task_ids = @{ $task_ids[0] } if ref($task_ids[0]);
118   foreach my $task_id (@task_ids) {
119     # find the inputs for this task_id
120     my %task_opts = map { $_ => $ARGS{$_} }
121                     grep /^$task_id-/, keys(%ARGS);
122     my $task_content = "===Create-Ticket: $task_id
123 CF-$CUSTOMFIELD_NAME" . q[
124 Depended-On-By: TOP
125 Owner: { $TOP->Owner }
126 { join("\n", map { "Requestor: $_" }
127   $TOP->Requestors->MemberEmailAddresses) }
128 ];
129     # any other attributes to put on subtask tickets should go here also.
130
131     my $has_content = 0;
132
133     # special case: automate prefixing the main ticket subject
134     if ( $task_opts{"$task_id-SubjectPrefix"} ) {
135       $task_opts{"$task_id-Subject"} =
136         $SUBJECT_PREFIX . $task_opts{"$task_id-Subject"};
137     }
138     
139     foreach my $key (sort keys %task_opts) {
140       $key =~ /^$task_id-(.*)/;
141       my $tag = $1;
142       my $value = $task_opts{$key};
143       $value =~ s/^\s*//;
144       $value =~ s/\s*$//;
145       $value =~ s/\r//g;
146       $task_content .= "$tag: $value\n";
147       # only create a task if the ticket has non-whitespace content
148       if ( lc($tag) eq 'content' and length($value) > 0 ) {
149         $task_content .= "ENDOFCONTENT\n";
150         $has_content = 1;
151       }
152     }
153     if ( $has_content ) {
154       $new_content .= $task_content;
155     }
156   }
157
158   # set up custom field, if necessary
159   if ( ! $CustomField->Id ) {
160     # should be RenderType 'Checkbox', but there isn't one yet...
161     my ($val, $msg) = $CustomField->Create(
162       Name          => $CUSTOMFIELD_NAME,
163       Type          => 'Select',
164       MaxValues     => 1,
165       LookupType    => 'RT::Queue-RT::Ticket',
166       Description   => 'Start subtasks for this ticket',
167       RenderType    => 'Dropdown',
168     );
169     if ($val) {
170       # should be impossible for this to fail
171       ($val, $msg) = $CustomField->AddValue(Name => 'Yes');
172     }
173     if (!$val) {
174       push @results, loc("Could not create ticket custom field: [_1]", $msg);
175     } else {
176       push @results, loc("Custom field created");
177     }
178   }
179
180   # apply CF to the queue, iff there are any tasks set up
181   if ( length($new_content) and ! $CustomField->IsApplied($Queue) ) {
182     my ($val, $msg) = $CustomField->AddToObject($QueueObj);
183     if (!$val) {
184       push @results, loc("Could not apply custom field to this queue: [_1]", $msg);
185     } else {
186       push @results, loc("Applied custom field to this queue");
187     }
188   } elsif ( ! length($new_content) and $CustomField->IsApplied($Queue) ) {
189     my ($val, $msg) = $CustomField->RemoveFromObject($QueueObj);
190     if (!$val) {
191       push @results, loc("Could not remove custom field from this queue: [_1]", $msg);
192     } else {
193       push @results, loc("Removed custom field from this queue");
194     }
195   }
196
197   if ( ! $Template->Id ) {
198     my ( $val, $msg ) = $Template->Create(
199       Queue           => $Queue,
200       Name            => $TEMPLATE_NAME,
201       Description     => 'Subtask tickets',
202       Type            => 'Perl',
203       Content         => $new_content,
204     );
205     if (!$val) {
206       push @results, loc("Could not create template: [_1]", $msg);
207     } else {
208       push @results, loc("Template created");
209     }
210   } elsif ( $Template->Content ne $new_content ) { # template needs updating
211     my ( $val, $msg ) = $Template->SetContent($new_content);
212     if (!$val) {
213       push @results, loc("Could not update template: [_1]", $msg);
214     } else {
215       push @results, loc("Template updated");
216     }
217   }
218
219   # Set up ScripCondition
220   if ( ! $ScripCondition->Id ) {
221     my ( $val, $msg ) = $ScripCondition->Create(
222       Name            => $SCRIPCONDITION_NAME,
223       Description     => "When CF.[$CUSTOMFIELD_NAME] equals 'Yes'",
224       ExecModule      => 'CustomFieldEquals',
225       Argument        => "$CUSTOMFIELD_NAME=Yes",
226       ApplicableTransTypes => 'Any',
227     );
228     if (!$val) {
229       push @results, loc("Could not create custom field condition: [_1]", $msg);
230     } else {
231       push @results, loc("Custom field condition created");
232     }
233   } elsif ( $ScripCondition->Argument ne "$CUSTOMFIELD_NAME=Yes" ) {
234     my ( $val, $msg ) = $ScripCondition->SetArgument("$CUSTOMFIELD_NAME=Yes");
235     if (!$val) {
236       push @results, loc("Could not set custom field condition: [_1]", $msg);
237     } else {
238       push @results, loc("Custom field condition set");
239     }
240   }
241
242   # Set up Scrip
243   if ( $Template->Id and ! $Scrip->Id ) {
244     my ($val, $msg) = $Scrip->Create(
245       Queue           => $Queue,
246       Template        => $Template->Id,
247       Description     => 'Create subtasks for ' . $QueueObj->Name,
248       ScripCondition  => $ScripCondition->Id,
249       ScripAction     => 'Create Tickets',
250     );
251     if (!$val) {
252       push @results, loc("Could not create scrip: [_1]", $msg);
253     } else {
254       push @results, loc("Scrip created");
255     }
256   } # else don't need to create the scrip
257
258   # even if $new_content is empty, there's no harm in letting the scrip and
259   # template exist with empty content. they just won't do anything.
260 }
261
262 # CHANGES HAVE BEEN SAVED.
263 # Now prepare to (re-)display the form.
264
265 # ask RT::Action::CreateTickets how it will parse the template
266 my $action_class = 'RT::Action::CreateTickets';
267 $action_class->require;
268 my $Action = $action_class->new(
269   CurrentUser    => $session{'CurrentUser'},
270 );
271 # this will populate $Action with the 'create_tickets' hash
272 $Action->Parse(
273   Content         => $Template->Content,
274   _ActiveContent  => 0,
275 );
276 my @task_ids;
277 @task_ids = @{ $Action->{create_tickets} } if exists $Action->{create_tickets};
278
279 </%init>
280 <%ARGS>
281 $Queue => undef         #queue id
282 </%ARGS>