import rt 3.8.8
[freeside.git] / rt / html / REST / 1.0 / Forms / ticket / default
1 %# BEGIN BPS TAGGED BLOCK {{{
2 %# 
3 %# COPYRIGHT:
4 %#  
5 %# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC 
6 %#                                          <jesse@bestpractical.com>
7 %# 
8 %# (Except where explicitly superseded by other copyright notices)
9 %# 
10 %# 
11 %# LICENSE:
12 %# 
13 %# This work is made available to you under the terms of Version 2 of
14 %# the GNU General Public License. A copy of that license should have
15 %# been provided with this software, but in any event can be snarfed
16 %# from www.gnu.org.
17 %# 
18 %# This work is distributed in the hope that it will be useful, but
19 %# WITHOUT ANY WARRANTY; without even the implied warranty of
20 %# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21 %# General Public License for more details.
22 %# 
23 %# You should have received a copy of the GNU General Public License
24 %# along with this program; if not, write to the Free Software
25 %# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 %# 02110-1301 or visit their web page on the internet at
27 %# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
28 %# 
29 %# 
30 %# CONTRIBUTION SUBMISSION POLICY:
31 %# 
32 %# (The following paragraph is not intended to limit the rights granted
33 %# to you to modify and distribute this software under the terms of
34 %# the GNU General Public License and is only of importance to you if
35 %# you choose to contribute your changes and enhancements to the
36 %# community by submitting them to Best Practical Solutions, LLC.)
37 %# 
38 %# By intentionally submitting any modifications, corrections or
39 %# derivatives to this work, or any other work intended for use with
40 %# Request Tracker, to Best Practical Solutions, LLC, you confirm that
41 %# you are the copyright holder for those contributions and you grant
42 %# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
43 %# royalty-free, perpetual, license to use, copy, create derivative
44 %# works based on those contributions, and sublicense and distribute
45 %# those contributions and any derivatives thereof.
46 %# 
47 %# END BPS TAGGED BLOCK }}}
48 %# REST/1.0/Forms/ticket/default
49 %#
50 <%ARGS>
51 $id
52 $changes => {}
53 $fields => undef
54 $args => undef
55 </%ARGS>
56 <%INIT>
57 use MIME::Entity;
58
59 my @comments;
60 my ($c, $o, $k, $e) = ("", [], {}, 0);
61 my %data   = %$changes;
62 my $ticket = new RT::Ticket $session{CurrentUser};
63 my @dates  = qw(Created Starts Started Due Resolved Told LastUpdated);
64 my @people = qw(Requestors Cc AdminCc);
65 my @create = qw(Queue Requestor Subject Cc AdminCc Owner Status Priority
66                 InitialPriority FinalPriority TimeEstimated TimeWorked
67                 TimeLeft Starts Started Due Resolved);
68 my @simple = qw(Subject Status Priority Disabled TimeEstimated TimeWorked
69                 TimeLeft InitialPriority FinalPriority);
70 my %dates  = map {lc $_ => $_} @dates;
71 my %people = map {lc $_ => $_} @people;
72 my %create = map {lc $_ => $_} @create;
73 my %simple = map {lc $_ => $_} @simple;
74
75 # Are we dealing with an existing ticket?
76 if ($id ne 'new') {
77     $ticket->Load($id);
78     if (!$ticket->Id) {
79         return [ "# Ticket $id does not exist.", [], {}, 1 ];
80     }
81     elsif (!$ticket->CurrentUserHasRight('ShowTicket') ||
82            (%data && !$ticket->CurrentUserHasRight('ModifyTicket')))
83     {
84         my $act = %data ? "modify" : "display";
85         return [ "# You are not allowed to $act ticket $id.", [], {}, 1 ];
86     }
87 }
88 else {
89     if (!keys(%data)) {
90         # GET ticket/new: Return a suitable default form.
91         # We get defaults from queue/1 (XXX: What if it isn't there?).
92         my $due = new RT::Date $session{CurrentUser};
93         my $queue = new RT::Queue $session{CurrentUser};
94         my $starts = new RT::Date $session{CurrentUser};
95         $queue->Load(1);
96         $due->SetToNow;
97         $due->AddDays($queue->DefaultDueIn) if $queue->DefaultDueIn;
98         $starts->SetToNow;
99
100         return [
101             "# Required: id, Queue",
102             [ qw(id Queue Requestor Subject Cc AdminCc Owner Status Priority
103                  InitialPriority FinalPriority TimeEstimated Starts Due Text) ],
104             {
105                 id               => "ticket/new",
106                 Queue            => $queue->Name,
107                 Requestor        => $session{CurrentUser}->Name,
108                 Subject          => "",
109                 Cc               => [],
110                 AdminCc          => [],
111                 Owner            => "",
112                 Status           => "new",
113                 Priority         => $queue->InitialPriority,
114                 InitialPriority  => $queue->InitialPriority,
115                 FinalPriority    => $queue->FinalPriority,
116                 TimeEstimated    => 0,
117                 Starts           => $starts->ISO,
118                 Due              => $due->ISO,
119                 Text             => "",
120             },
121             0
122         ];
123     }
124     else {
125         # We'll create a new ticket, and fall through to set fields that
126         # can't be set in the call to Create().
127         my (%v, $text);
128
129         foreach my $k (keys %data) {
130             if (exists $create{lc $k}) {
131                 $v{$create{lc $k}} = delete $data{$k};
132             }
133             # Set custom field
134             elsif ($k =~ /^CF-/i) {
135                 my $cf = RT::CustomField->new( $RT::SystemUser );
136                 my $cfk = $k;
137                 $cfk =~ s/^CF-//i;
138                 unless($cf->LoadByName( Name => $cfk )) {
139                     push @comments, "# Invalid custom field name ($cfk)";
140                     delete $data{$k};
141                     next;
142                 }
143                 $v{"CustomField-".$cf->Id()} = delete $data{$k};
144             }
145             elsif (lc $k eq 'text') {
146                 $text = delete $data{$k};
147             }
148         }
149
150         # people fields allow multiple values
151         $v{$_} = vsplit($v{$_}) foreach ( grep $create{lc $_}, @people );
152
153         if ($text) {
154             $v{MIMEObj} =
155                 MIME::Entity->build(
156                     From => $session{CurrentUser}->EmailAddress,
157                     Subject => $v{Subject},
158                     Data => $text
159                 );
160         }
161
162         my($tid,$trid,$terr) = $ticket->Create(%v);    
163         unless ($tid) {
164             push(@comments, "# Could not create ticket.");
165             push(@comments, "# " . $terr);
166             goto DONE;
167         }
168
169         delete $data{id};
170         $id = $ticket->Id;
171         push(@comments, "# Ticket $id created.");
172         # see if the hash is empty
173         goto DONE if ! keys(%data);
174     }
175 }
176
177 # Now we know we're dealing with an existing ticket.
178 if (!keys(%data)) {
179     my ($time, $key, $val, @data);
180
181     push @data, [ id    => "ticket/".$ticket->Id   ];
182     push @data, [ Queue => $ticket->QueueObj->Name ] 
183         if (!%$fields || exists $fields->{lc 'Queue'});
184     push @data, [ Owner => $ticket->OwnerObj->Name ]
185         if (!%$fields || exists $fields->{lc 'Owner'});
186     push @data, [ Creator => $ticket->CreatorObj->Name ]
187         if (!%$fields || exists $fields->{lc 'Creator'});
188
189     foreach (qw(Subject Status Priority InitialPriority FinalPriority)) {
190         next unless (!%$fields || (exists $fields->{lc $_}));
191         push @data, [$_ => $ticket->$_ ];
192     }
193
194     foreach $key (@people) {
195         next unless (!%$fields || (exists $fields->{lc $key}));
196         push @data, [ $key => [ $ticket->$key->MemberEmailAddresses ] ];
197     }
198
199     $time = new RT::Date ($session{CurrentUser});
200     foreach $key (@dates) {
201         next unless (!%$fields || (exists $fields->{lc $key}));
202         $time->Set(Format => 'sql', Value => $ticket->$key);
203         push @data, [ $key => $time->AsString ];
204     }
205
206     $time = new RT::Date ($session{CurrentUser});
207     foreach $key (qw(TimeEstimated TimeWorked TimeLeft)) {
208         next unless (!%$fields || (exists $fields->{lc $key}));
209         $val = $ticket->$key || 0;
210         $val = "$val minutes" if $val;
211         push @data, [ $key => $val ];
212     }
213
214     # Display custom fields
215     my $CustomFields = $ticket->QueueObj->TicketCustomFields();
216     while (my $cf = $CustomFields->Next()) {
217         next unless (!%$fields || (exists $fields->{"cf-".lc $cf->Name}));
218         my $vals = $ticket->CustomFieldValues($cf->Id());
219         my @out = ();
220         while (my $v = $vals->Next()) {
221             push @out, $v->Content;
222         }
223         push @data, [ 'CF-' . $cf->Name => join ',', @out ];
224     }
225
226     my %k = map {@$_} @data;
227     $o = [ map {$_->[0]} @data ];
228     $k = \%k;
229 }
230 else {
231     my ($get, $set, $key, $val, $n, $s);
232
233     foreach $key (keys %data) {
234         $val = $data{$key};
235         $key = lc $key;
236         $n = 1;
237
238         if (ref $val eq 'ARRAY') {
239             unless ($key =~ /^(?:Requestors|Cc|AdminCc)$/i) {
240                 $n = 0;
241                 $s = "$key may have only one value.";
242                 goto SET;
243             }
244         }
245
246         if ($key =~ /^queue$/i) {
247             next if $val eq $ticket->QueueObj->Name;
248             ($n, $s) = $ticket->SetQueue($val);
249         }
250         elsif ($key =~ /^owner$/i) {
251             next if $val eq $ticket->OwnerObj->Name;
252             ($n, $s) = $ticket->SetOwner($val);
253         }
254         elsif (exists $simple{$key}) {
255             $key = $simple{$key};
256             $set = "Set$key";
257
258             next if (($val eq $ticket->$key)|| ($ticket->$key =~ /^\d+$/ && $val == $ticket->$key));
259             ($n, $s) = $ticket->$set("$val");
260         }
261         elsif (exists $dates{$key}) {
262             $key = $dates{$key};
263             $set = "Set$key";
264
265             my $time = new RT::Date $session{CurrentUser};
266             $time->Set(Format => 'sql', Value => $ticket->$key);
267             next if ($val =~ /^not set$/i || $val eq $time->AsString);
268             ($n, $s) = $ticket->$set($val);
269         }
270         elsif (exists $people{$key}) {
271             $key = $people{$key};
272             my ($p, @msgs);
273
274             my %new  = map {$_=>1} @{ vsplit($val) };
275             my %old  = map {$_=>1} $ticket->$key->MemberEmailAddresses;
276             my $type = $key eq 'Requestors' ? 'Requestor' : $key;
277
278             foreach $p (keys %old) {
279                 unless (exists $new{$p}) {
280                     ($s, $n) = $ticket->DeleteWatcher(Type => $type,
281                                                       Email => $p);
282                     push @msgs, [ $s, $n ];
283                 }
284             }
285             foreach $p (keys %new) {
286                 # XXX: This is a stupid test.
287                 unless ($p =~ /^[\w.+-]+\@([\w.-]+\.)*\w+.?$/) {
288                     $s = 0;
289                     $n = "$p is not a valid email address.";
290                     push @msgs, [ $s, $n ];
291                     next;
292                 }
293                 unless ($ticket->IsWatcher(Type => $type, Email => $p)) {
294                     ($s, $n) = $ticket->AddWatcher(Type => $type,
295                                                    Email => $p);
296                     push @msgs, [ $s, $n ];
297                 }
298             }
299
300             $n = 1;
301             if (@msgs = grep {$_->[0] == 0} @msgs) {
302                 $n = 0;
303                 $s = join "\n", map {"# ".$_->[1]} @msgs;
304                 $s =~ s/^# //;
305             }
306         }
307         # Set custom field
308         elsif ($key =~ /^CF-/i) {
309             my $cf = RT::CustomField->new( $RT::SystemUser );
310             $key =~ s/^CF-//i;
311             if (not $cf->LoadByName( Name => $key )) {
312                 $n = 0;
313                 $s = "Unknown custom field.";
314             }
315             else {
316                 ($n, $s) = $ticket->AddCustomFieldValue(
317                              Field => $cf, Value => $val );
318                 $s =~ s/^# // if defined $s;
319             }
320         }
321         elsif ($key ne 'id' && $key ne 'type' && $key ne 'creator') {
322             $n = 0;
323             $s = "Unknown field.";
324         }
325
326     SET:
327         if ($n == 0) {
328             $e = 1;
329             push @comments, "# $key: $s";
330             unless (@$o) {
331                 my %o = keys %$changes;
332                 delete $o{id};
333                 @$o = ("id", keys %o);
334                 $k = $changes;
335             }
336         }
337     }
338     push(@comments, "# Ticket ".$ticket->id." updated.") unless $n == 0;
339 }
340
341 DONE:
342 $c ||= join("\n", @comments) if @comments;
343 return [$c, $o, $k, $e];
344
345 </%INIT>