diff options
Diffstat (limited to 'rt/share/html/REST/1.0/Forms/ticket/default')
-rwxr-xr-x | rt/share/html/REST/1.0/Forms/ticket/default | 447 |
1 files changed, 447 insertions, 0 deletions
diff --git a/rt/share/html/REST/1.0/Forms/ticket/default b/rt/share/html/REST/1.0/Forms/ticket/default new file mode 100755 index 0000000..b82cb5e --- /dev/null +++ b/rt/share/html/REST/1.0/Forms/ticket/default @@ -0,0 +1,447 @@ +%# BEGIN BPS TAGGED BLOCK {{{ +%# +%# COPYRIGHT: +%# +%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC +%# <jesse@bestpractical.com> +%# +%# (Except where explicitly superseded by other copyright notices) +%# +%# +%# LICENSE: +%# +%# This work is made available to you under the terms of Version 2 of +%# the GNU General Public License. A copy of that license should have +%# been provided with this software, but in any event can be snarfed +%# from www.gnu.org. +%# +%# This work is distributed in the hope that it will be useful, but +%# WITHOUT ANY WARRANTY; without even the implied warranty of +%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +%# General Public License for more details. +%# +%# You should have received a copy of the GNU General Public License +%# along with this program; if not, write to the Free Software +%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +%# 02110-1301 or visit their web page on the internet at +%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. +%# +%# +%# CONTRIBUTION SUBMISSION POLICY: +%# +%# (The following paragraph is not intended to limit the rights granted +%# to you to modify and distribute this software under the terms of +%# the GNU General Public License and is only of importance to you if +%# you choose to contribute your changes and enhancements to the +%# community by submitting them to Best Practical Solutions, LLC.) +%# +%# By intentionally submitting any modifications, corrections or +%# derivatives to this work, or any other work intended for use with +%# Request Tracker, to Best Practical Solutions, LLC, you confirm that +%# you are the copyright holder for those contributions and you grant +%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable, +%# royalty-free, perpetual, license to use, copy, create derivative +%# works based on those contributions, and sublicense and distribute +%# those contributions and any derivatives thereof. +%# +%# END BPS TAGGED BLOCK }}} +%# REST/1.0/Forms/ticket/default +%# +<%ARGS> +$id +$changes => {} +$fields => undef +$args => undef +</%ARGS> +<%INIT> +use MIME::Entity; +use RT::Interface::REST; + +my $cf_spec = RT::Interface::REST->custom_field_spec(1); + +my @comments; +my ($c, $o, $k, $e) = ("", [], {}, 0); +my %data = %$changes; +my $ticket = new RT::Ticket $session{CurrentUser}; +my @dates = qw(Created Starts Started Due Resolved Told LastUpdated); +my @people = qw(Requestors Cc AdminCc); +my @create = qw(Queue Requestor Subject Cc AdminCc Owner Status Priority + InitialPriority FinalPriority TimeEstimated TimeWorked + TimeLeft Starts Started Due Resolved); +my @simple = qw(Subject Status Priority Disabled TimeEstimated TimeWorked + TimeLeft InitialPriority FinalPriority); +my %dates = map {lc $_ => $_} @dates; +my %people = map {lc $_ => $_} @people; +my %create = map {lc $_ => $_} @create; +my %simple = map {lc $_ => $_} @simple; + +# Are we dealing with an existing ticket? +if ($id ne 'new') { + $ticket->Load($id); + if (!$ticket->Id) { + return [ "# Ticket $id does not exist.", [], {}, 1 ]; + } + elsif (!$ticket->CurrentUserHasRight('ShowTicket') || + (%data && !$ticket->CurrentUserHasRight('ModifyTicket'))) + { + my $act = %data ? "modify" : "display"; + return [ "# You are not allowed to $act ticket $id.", [], {}, 1 ]; + } +} +else { + if (!keys(%data)) { + # GET ticket/new: Return a suitable default form. + # We get defaults from queue/1 (XXX: What if it isn't there?). + my $due = new RT::Date $session{CurrentUser}; + my $queue = new RT::Queue $session{CurrentUser}; + my $starts = new RT::Date $session{CurrentUser}; + $queue->Load(1); + $due->SetToNow; + $due->AddDays($queue->DefaultDueIn) if $queue->DefaultDueIn; + $starts->SetToNow; + + return [ + "# Required: id, Queue", + [ qw(id Queue Requestor Subject Cc AdminCc Owner Status Priority + InitialPriority FinalPriority TimeEstimated Starts Due Text) ], + { + id => "ticket/new", + Queue => $queue->Name, + Requestor => $session{CurrentUser}->Name, + Subject => "", + Cc => [], + AdminCc => [], + Owner => "", + Status => "new", + Priority => $queue->InitialPriority, + InitialPriority => $queue->InitialPriority, + FinalPriority => $queue->FinalPriority, + TimeEstimated => 0, + Starts => $starts->ISO, + Due => $due->ISO, + Text => "", + }, + 0 + ]; + } + else { + # We'll create a new ticket, and fall through to set fields that + # can't be set in the call to Create(). + my (%v, $text); + + foreach my $k (keys %data) { + # flexibly parse any dates + if ($dates{lc $k}) { + my $time = new RT::Date $session{CurrentUser}; + $time->Set(Format => 'unknown', Value => $data{$k}); + $data{$k} = $time->ISO; + } + + if (exists $create{lc $k}) { + $v{$create{lc $k}} = delete $data{$k}; + } + # Set custom field + elsif ($k =~ /^$cf_spec/) { + my $cf = RT::CustomField->new( $RT::SystemUser ); + my $cfk = $1 || $2; + unless($cf->LoadByName( Name => $cfk )) { + push @comments, "# Invalid custom field name ($cfk)"; + delete $data{$k}; + next; + } + $v{"CustomField-".$cf->Id()} = delete $data{$k}; + } + elsif (lc $k eq 'text') { + $text = delete $data{$k}; + } + } + + # people fields allow multiple values + $v{$_} = vsplit($v{$_}) foreach ( grep $create{lc $_}, @people ); + + if ($text) { + $v{MIMEObj} = + MIME::Entity->build( + From => $session{CurrentUser}->EmailAddress, + Subject => $v{Subject}, + Data => $text + ); + } + + my($tid,$trid,$terr) = $ticket->Create(%v); + unless ($tid) { + push(@comments, "# Could not create ticket."); + push(@comments, "# " . $terr); + goto DONE; + } + + delete $data{id}; + $id = $ticket->Id; + push(@comments, "# Ticket $id created."); + # see if the hash is empty + goto DONE if ! keys(%data); + } +} + +# Now we know we're dealing with an existing ticket. +if (!keys(%data)) { + my ($time, $key, $val, @data); + + push @data, [ id => "ticket/".$ticket->Id ]; + push @data, [ Queue => $ticket->QueueObj->Name ] + if (!%$fields || exists $fields->{lc 'Queue'}); + push @data, [ Owner => $ticket->OwnerObj->Name ] + if (!%$fields || exists $fields->{lc 'Owner'}); + push @data, [ Creator => $ticket->CreatorObj->Name ] + if (!%$fields || exists $fields->{lc 'Creator'}); + + foreach (qw(Subject Status Priority InitialPriority FinalPriority)) { + next unless (!%$fields || (exists $fields->{lc $_})); + push @data, [$_ => $ticket->$_ ]; + } + + foreach $key (@people) { + next unless (!%$fields || (exists $fields->{lc $key})); + push @data, [ $key => [ $ticket->$key->MemberEmailAddresses ] ]; + } + + $time = new RT::Date ($session{CurrentUser}); + foreach $key (@dates) { + next unless (!%$fields || (exists $fields->{lc $key})); + $time->Set(Format => 'sql', Value => $ticket->$key); + push @data, [ $key => $time->AsString ]; + } + + $time = new RT::Date ($session{CurrentUser}); + foreach $key (qw(TimeEstimated TimeWorked TimeLeft)) { + next unless (!%$fields || (exists $fields->{lc $key})); + $val = $ticket->$key || 0; + $val = "$val minutes" if $val; + push @data, [ $key => $val ]; + } + + # Display custom fields + my $CustomFields = $ticket->CustomFields; + while (my $cf = $CustomFields->Next()) { + next unless !%$fields + || exists $fields->{"cf.{".lc($cf->Name)."}"} + || exists $fields->{"cf-".lc $cf->Name}; + + my $vals = $ticket->CustomFieldValues($cf->Id()); + my @out = (); + if ( $cf->SingleValue ) { + my $v = $vals->Next; + push @out, $v->Content if $v; + } + else { + while (my $v = $vals->Next()) { + my $content = $v->Content; + $content =~ s/'/\\'/g; + if ( $v->Content =~ /,/ ) { + push @out, q{'} . $content . q{'}; + } + else { + push @out, $content; + } + } + } + push @data, [ ('CF.{' . $cf->Name . '}') => join ',', @out ]; + } + + my %k = map {@$_} @data; + $o = [ map {$_->[0]} @data ]; + $k = \%k; +} +else { + my ($get, $set, $key, $val, $n, $s); + + foreach $key (keys %data) { + $val = $data{$key}; + $key = lc $key; + $n = 1; + + if (ref $val eq 'ARRAY') { + unless ($key =~ /^(?:Requestors|Cc|AdminCc)$/i) { + $n = 0; + $s = "$key may have only one value."; + goto SET; + } + } + + if ($key =~ /^queue$/i) { + next if $val eq $ticket->QueueObj->Name; + ($n, $s) = $ticket->SetQueue($val); + } + elsif ($key =~ /^owner$/i) { + next if $val eq $ticket->OwnerObj->Name; + ($n, $s) = $ticket->SetOwner($val); + } + elsif (exists $simple{$key}) { + $key = $simple{$key}; + $set = "Set$key"; + + next if (($val eq $ticket->$key)|| ($ticket->$key =~ /^\d+$/ && $val == $ticket->$key)); + ($n, $s) = $ticket->$set("$val"); + } + elsif (exists $dates{$key}) { + $key = $dates{$key}; + + # We try to detect whether it should update a field by checking + # whether its current value equals the entered value. Since the + # LastUpdated field is automatically updated as other columns are + # changed, it is not properly skipped. Users cannot update this + # field anyway. + next if $key eq 'LastUpdated'; + + $set = "Set$key"; + + my $time = new RT::Date $session{CurrentUser}; + $time->Set(Format => 'sql', Value => $ticket->$key); + next if ($val =~ /^not set$/i || $val eq $time->AsString); + + $time->Set(Format => 'unknown', Value => $val); + ($n, $s) = $ticket->$set($time->ISO); + } + elsif (exists $people{$key}) { + $key = $people{$key}; + my ($p, @msgs); + + my %new = map {$_=>1} @{ vsplit($val) }; + my %old = map {$_=>1} $ticket->$key->MemberEmailAddresses; + my $type = $key eq 'Requestors' ? 'Requestor' : $key; + + foreach $p (keys %old) { + unless (exists $new{$p}) { + ($s, $n) = $ticket->DeleteWatcher(Type => $type, + Email => $p); + push @msgs, [ $s, $n ]; + } + } + foreach $p (keys %new) { + # XXX: This is a stupid test. + unless ($p =~ /^[\w.+-]+\@([\w.-]+\.)*\w+.?$/) { + $s = 0; + $n = "$p is not a valid email address."; + push @msgs, [ $s, $n ]; + next; + } + unless ($ticket->IsWatcher(Type => $type, Email => $p)) { + ($s, $n) = $ticket->AddWatcher(Type => $type, + Email => $p); + push @msgs, [ $s, $n ]; + } + } + + $n = 1; + if (@msgs = grep {$_->[0] == 0} @msgs) { + $n = 0; + $s = join "\n", map {"# ".$_->[1]} @msgs; + $s =~ s/^# //; + } + } + # Set custom field + elsif ($key =~ /^$cf_spec/) { + my $cf = RT::CustomField->new( $RT::SystemUser ); + $key = $1 || $2; + if (not $cf->LoadByName( Name => $key )) { + $n = 0; + $s = "Unknown custom field."; + } + else { + my $vals = $ticket->CustomFieldValues($cf->id); + + if ( $cf->SingleValue ) { + my $old = $vals->Next; + if ( $old ) { + if ( $val ne $old->Content ) { + $old->Delete; + ($n, $s) = $ticket->AddCustomFieldValue( + Field => $cf, Value => $val ); + $s =~ s/^# // if defined $s; + } + } + else { + ($n, $s) = $ticket->AddCustomFieldValue( + Field => $cf, Value => $val ); + $s =~ s/^# // if defined $s; + } + } + else { + my @new; + my ( $a, $b ) = split /,/, $val, 2; + while ($a) { + no warnings 'uninitialized'; + if ( $a =~ /^'/ ) { + my $s = $a; + while ( $a !~ /'$/ || ( $a !~ /(\\\\)+'$/ + && $a =~ /(\\)+'$/ ) ) { + ( $a, $b ) = split /,/, $b, 2; + $s .= ',' . $a; + } + $s =~ s/^'//; + $s =~ s/'$//; + $s =~ s/\\'/'/g; + push @new, $s; + } + elsif ( $a =~ /^q{/ ) { + my $s = $a; + while ( $a !~ /}$/ ) { + ( $a, $b ) = split /,/, $b, 2; + $s .= ',' . $a; + } + $s =~ s/^q{//; + $s =~ s/}//; + push @new, $s; + } + else { + push @new, $a; + } + ( $a, $b ) = split /,/, $b, 2; + } + + my %new; + $new{$_}++ for @new; + + while (my $v = $vals->Next()) { + my $c = $v->Content; + if ( $new{$c} ) { + $new{$c}--; + } + else { + $v->Delete(); + } + } + for ( @new ) { + while ( $new{$_} && $new{$_}-- ) { + ($n, $s) = $ticket->AddCustomFieldValue( + Field => $cf, Value => $_ ); + $s =~ s/^# // if defined $s; + } + } + } + } + } + elsif ($key ne 'id' && $key ne 'type' && $key ne 'creator') { + $n = 0; + $s = "Unknown field."; + } + + SET: + if ($n == 0) { + $e = 1; + push @comments, "# $key: $s"; + unless (@$o) { + # move id forward + @$o = ("id", grep { $_ ne 'id' } keys %$changes); + $k = $changes; + } + } + } + push(@comments, "# Ticket ".$ticket->id." updated.") unless $n == 0; +} + +DONE: +$c ||= join("\n", @comments) if @comments; +return [$c, $o, $k, $e]; + +</%INIT> |