%# REST/1.0/Forms/ticket/default %# <%ARGS> $id $changes => {} $fields => undef <%perl> use MIME::Entity; 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); 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 (%data == 0) { # 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: Queue, Requestor, Subject", [ 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) { if (exists $create{lc $k}) { $v{$create{lc $k}} = delete $data{$k}; } elsif (lc $k eq 'text') { $text = delete $data{$k}; } } if ($text) { $v{MIMEObj} = MIME::Entity->build( From => $session{CurrentUser}->EmailAddress, Subject => $v{Subject}, Data => $text ); } $ticket->Create(%v); unless ($ticket->Id) { return [ "# Could not create ticket.", [], {}, 1 ]; } delete $data{id}; $id = $ticket->Id; push(@comments, "# Ticket $id created."); goto DONE if %data == 0; } } # Now we know we're dealing with an existing ticket. if (%data == 0) { 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 = $time->DurationAsString($val*60) if $val; push @data, [ $key => $val ]; } 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; ($n, $s) = $ticket->$set($val); } elsif (exists $dates{$key}) { $key = $dates{$key}; $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); ($n, $s) = $ticket->$set($val); } 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/^# //; } } elsif ($key ne 'id' && $key ne 'type') { $n = 0; $s = "Unknown field."; } SET: if ($n == 0) { $e = 1; push @comments, "# $key: $s"; unless (@$o) { my %o = keys %$changes; delete $o{id}; @$o = ("id", keys %o); $k = $changes; } } } push(@comments, "# Ticket ".$ticket->id." updated.") unless $n == 0; } DONE: $c ||= join("\n", @comments) if @comments; return [$c, $o, $k, $e];