rt 4.2.14 (#13852)
[freeside.git] / rt / share / html / Ticket / Display.html
index f8eaf39..2851d0b 100755 (executable)
@@ -1,40 +1,40 @@
 %# BEGIN BPS TAGGED BLOCK {{{
-%# 
+%#
 %# COPYRIGHT:
-%# 
-%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
-%#                                          <jesse@bestpractical.com>
-%# 
+%#
+%# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
+%#                                          <sales@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
 %# 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 }}}
 <& /Elements/Header, 
-    Title => loc("#[_1]: [_2]", $TicketObj->Id, $TicketObj->Subject),
+    Title => $title,
     LinkRel => \%link_rel &>
-<& /Ticket/Elements/Tabs, 
-    Ticket => $TicketObj, 
-    current_tab => 'Ticket/Display.html?id='.$TicketObj->id,
-    Title => loc("#[_1]: [_2]", $TicketObj->Id, $TicketObj->Subject) &>
+<& /Elements/Tabs &>
 
 % $m->callback(CallbackName => 'BeforeActionList', %ARGS, Actions => \@Actions, ARGSRef => \%ARGS, Ticket => $TicketObj);
 
 <& /Elements/ListActions, actions => \@Actions &>
 <& Elements/ShowUpdateStatus, Ticket => $TicketObj &>
+<& Elements/ShowDependencyStatus, Ticket => $TicketObj &>
 
-% $m->callback( %ARGS, Ticket => $TicketObj, CallbackName => 'BeforeShowSummary' );
+% $m->callback( %ARGS, Ticket => $TicketObj, Transactions => $transactions, Attachments => $attachments, CallbackName => 'BeforeShowSummary' );
 <div class="summary">
 <&| /Widgets/TitleBox, title => loc('Ticket metadata') &>
 <& /Ticket/Elements/ShowSummary,  Ticket => $TicketObj, Attachments => $attachments &>
 </div>
 <br />
 
-% $m->callback( Ticket => $TicketObj, %ARGS, CallbackName => 'BeforeShowHistory' );
-
-<& /Ticket/Elements/ShowHistory , 
-      Ticket => $TicketObj, 
-      Tickets => $Tickets, 
-      Collapsed => $ARGS{'Collapsed'}, 
-      ShowHeaders => $ARGS{'ShowHeaders'},
-      Attachments => $attachments,
-      AttachmentContent => $attachment_content
-&> 
+% $m->callback( Ticket => $TicketObj, %ARGS, Transactions => $transactions, Attachments => $attachments, CallbackName => 'BeforeShowHistory' );
+
+% my $ShowHistory = RT->Config->Get("ShowHistory", $session{'CurrentUser'});
+% if ($ShowHistory eq "delay") {
+    <& /Ticket/Elements/DelayShowHistory,
+        Ticket => $TicketObj,
+        ShowHeaders => $ARGS{'ShowHeaders'},
+    &>
+% } elsif (not $ForceShowHistory and $ShowHistory eq "click") {
+    <& /Ticket/Elements/ClickToShowHistory,
+        Ticket => $TicketObj,
+        ShowHeaders => $ARGS{'ShowHeaders'},
+    &>
+% } else {
+    <& /Elements/ShowHistory ,
+          Object => $TicketObj,
+          Transactions => $transactions,
+          ShowHeaders => $ARGS{'ShowHeaders'},
+          Attachments => $attachments,
+          AttachmentContent => $attachment_content
+    &>
+% }
 
 % $m->callback( %ARGS,
 %     Ticket       => $TicketObj,
-%     current_tab  => 'Ticket/Display.html?id=' . $TicketObj->id,
+%     Transactions => $transactions,
+%     Attachments  => $attachments,
 %     CallbackName => 'AfterShowHistory',
 % );
 
 $id => undef
 $TicketObj => undef
 $ShowHeaders => 0
-$Collapsed => undef
+$ForceShowHistory => 0
+$RedirectToBasics => 0
 </%ARGS>
 
 <%INIT>
 
 $m->callback( TicketObj => $TicketObj, ARGSRef => \%ARGS, CallbackName => 'Initial' );
 
-my (@Actions, $Tickets);  
+if ( ! $ARGS{'NoRedirect'} && RT::Interface::Web->MobileClient()) {
+    $id ||= $TicketObj->id if $TicketObj;
+    RT::Interface::Web::Redirect(RT->Config->Get('WebURL').'m/ticket/show?id='.$id);
+    $m->abort;
+}
+
+
+my (@Actions, $title);
 
 
 unless ($id || $TicketObj) {
@@ -102,9 +121,17 @@ unless ($id || $TicketObj) {
 }
 
 if ($ARGS{'id'} eq 'new') {
-    # {{{ Create a new ticket
+    # Create a new ticket
+
+    # Massage customer IDs into member links.
+    my @cust_uris = map { 
+      /^(\d+)$/ && "freeside://freeside/cust_main/$1"
+    } split(' ', $ARGS{'new-Customer'});
+    
+    $ARGS{'new-MemberOf'} = 
+      join(' ', $ARGS{'new-MemberOf'}, @cust_uris);
 
-    my $Queue = new RT::Queue( $session{'CurrentUser'} );
+    my $Queue = RT::Queue->new( $session{'CurrentUser'} );
     $Queue->Load($ARGS{'Queue'});
     unless ( $Queue->id ) {
         Abort('Queue not found');
@@ -114,87 +141,99 @@ if ($ARGS{'id'} eq 'new') {
         Abort('You have no permission to create tickets in that queue.');
     }
 
-    ($TicketObj, @Actions) = CreateTicket(
-        Attachments => delete $session{'Attachments'},
-        %ARGS,
-    );
+    ($TicketObj, @Actions) = CreateTicket( %ARGS );
     unless ( $TicketObj->CurrentUserHasRight('ShowTicket') ) {
         Abort("No permission to view newly created ticket #".$TicketObj->id.".");
     }
-    # }}}
 } else { 
     $TicketObj ||= LoadTicket($ARGS{'id'});
 
+    $TicketObj->CurrentUser->PrincipalObj->HasRights( Object => $TicketObj );
+
+    my $SkipProcessing;
+
     $m->callback( CallbackName => 'BeforeProcessArguments',
-        TicketObj => $TicketObj, Tickets => $Tickets,
-        ActionsRef => \@Actions, ARGSRef => \%ARGS );
-    if ( defined $ARGS{'Action'} ) {
-        if ($ARGS{'Action'} =~ /^(Steal|Kill|Take|SetTold)$/) {
-            my $action = $1;
-            my ($res, $msg) = $TicketObj->$action();
-            push(@Actions, $msg);
+        TicketObj => $TicketObj,
+        ActionsRef => \@Actions, ARGSRef => \%ARGS,
+        SkipProcessing => \$SkipProcessing );
+
+    if ( !$SkipProcessing ) {
+        if ( defined $ARGS{'Action'} ) {
+            if ($ARGS{'Action'} =~ /^(Steal|Delete|Take|SetTold)$/) {
+                my $action = $1;
+                my ($res, $msg) = $TicketObj->$action();
+                push(@Actions, $msg);
+            }
         }
-    }
 
-    $m->callback(CallbackName => 'ProcessArguments', 
-            Ticket => $TicketObj, 
-            ARGSRef => \%ARGS, 
-            Actions => \@Actions);
-    
-    $ARGS{UpdateAttachments} = $session{'Attachments'};
-    push @Actions,
-        ProcessUpdateMessage(
-        ARGSRef   => \%ARGS,
-        Actions   => \@Actions,
-        TicketObj => $TicketObj,
+        $m->callback(CallbackName => 'ProcessArguments', 
+                Ticket => $TicketObj, 
+                ARGSRef => \%ARGS, 
+                Actions => \@Actions);
+        
+        push @Actions, ProcessUpdateMessage(
+            ARGSRef   => \%ARGS,
+            Actions   => \@Actions,
+            TicketObj => $TicketObj,
         );
-    delete $session{'Attachments'};
-
-    #Process status updates
-    push @Actions, ProcessTicketWatchers(ARGSRef => \%ARGS, TicketObj => $TicketObj );
-    push @Actions, ProcessTicketBasics(  ARGSRef => \%ARGS, TicketObj => $TicketObj );
-    push @Actions, ProcessTicketLinks(   ARGSRef => \%ARGS, TicketObj => $TicketObj );
-    push @Actions, ProcessTicketDates(   ARGSRef => \%ARGS, TicketObj => $TicketObj );
-    push @Actions, ProcessObjectCustomFieldUpdates(ARGSRef => \%ARGS, TicketObj => $TicketObj );
-
-    # XXX: we shouldn't block actions here if user has no right to see the ticket,
-    # but we should allow him to see actions he has done
-    unless ($TicketObj->CurrentUserHasRight('ShowTicket')) {
-        Abort("No permission to view ticket");
-    }
-    if ( $ARGS{'MarkAsSeen'} ) {
-        $TicketObj->SetAttribute(
-            Name => 'User-'. $TicketObj->CurrentUser->id .'-SeenUpTo',
-            Content => $TicketObj->LastUpdated,
-        );
-        push @Actions, loc('Marked all messages as seen');
+
+        #Process status updates
+        push @Actions, ProcessTicketWatchers(ARGSRef => \%ARGS, TicketObj => $TicketObj );
+        push @Actions, ProcessTicketBasics(  ARGSRef => \%ARGS, TicketObj => $TicketObj );
+        push @Actions, ProcessTicketLinks(   ARGSRef => \%ARGS, TicketObj => $TicketObj );
+        push @Actions, ProcessTicketDates(   ARGSRef => \%ARGS, TicketObj => $TicketObj );
+        push @Actions, ProcessObjectCustomFieldUpdates(ARGSRef => \%ARGS, TicketObj => $TicketObj );
+        # If this fails due to required fields being empty, it will set
+        # notes('RedirectToBasics').
+        push @Actions, ProcessTicketStatus(  ARGSRef => \%ARGS, TicketObj => $TicketObj );
+
+        push @Actions, ProcessTicketReminders( ARGSRef => \%ARGS, TicketObj => $TicketObj );
+
+        unless ($TicketObj->CurrentUserHasRight('ShowTicket')) {
+            if (@Actions) {
+                Abort("A change was applied successfully, but you no longer have permissions to view the ticket", Actions => \@Actions);
+            } else {
+                Abort("No permission to view ticket");
+            }
+        }
+        if ( $ARGS{'MarkAsSeen'} ) {
+            $TicketObj->SetAttribute(
+                Name => 'User-'. $TicketObj->CurrentUser->id .'-SeenUpTo',
+                Content => $TicketObj->LastUpdated,
+            );
+            push @Actions, loc('Marked all messages as seen');
+        }
     }
 }
 
+
+$title = loc("Ticket #[_1]: [_2]", $TicketObj->Id, $TicketObj->Subject || '');
+
 $m->callback(
     CallbackName => 'BeforeDisplay',
     TicketObj => \$TicketObj,
-    Tickets => \$Tickets,
     Actions => \@Actions,
+    title => \$title,
     ARGSRef => \%ARGS,
 );
 
 # This code does automatic redirection if any updates happen. 
+$m->notes('RedirectToBasics' => 1) if $RedirectToBasics;
+my $path = '/Ticket/'. ( $m->notes('RedirectToBasics') ? 'Modify.html'
+                                                       : 'Display.html' );
+MaybeRedirectForResults(
+    Actions   => \@Actions,
+    $TicketObj->Type eq 'approval' && RT->Config->Get('ForceApprovalsView')
+        ? (Path      => "/Approvals/Display.html", Force => 1)
+        : (Path      => $path)
+    ,
+    Anchor    => $ARGS{'Anchor'},
+    Arguments => { id => $TicketObj->id },
+);
 
-if (@Actions) {
-
-    # We've done something, so we need to clear the decks to avoid
-    # resubmission on refresh.
-    # But we need to store Actions somewhere too, so we don't lose them.
-    my $key = Digest::MD5::md5_hex( rand(1024) );
-    push @{ $session{"Actions"}->{$key} ||= [] }, @Actions;
-    $session{'i'}++;
-    RT::Interface::Web::Redirect( RT->Config->Get('WebURL') . "Ticket/Display.html?id=" . $TicketObj->id . "&results=" . $key );
-
-}
-
-my $attachments = $m->comp('Elements/FindAttachments', Ticket => $TicketObj, Tickets => $Tickets);
-my $attachment_content = $m->comp('Elements/LoadTextAttachments', Ticket => $TicketObj);
+my $transactions = $TicketObj->SortedTransactions;
+my $attachments = $TicketObj->Attachments;
+my $attachment_content = $TicketObj->TextAttachments;
 
 my %link_rel;
 if (defined $session{'tickets'} and ($ARGS{'Query'} or $session{'CurrentSearchHash'}->{'Query'})) {
@@ -202,6 +241,6 @@ if (defined $session{'tickets'} and ($ARGS{'Query'} or $session{'CurrentSearchHa
     $link_rel{first} = "Ticket/Display.html?id=" . $item_map->{first}                if $item_map->{$TicketObj->Id}{prev};
     $link_rel{prev}  = "Ticket/Display.html?id=" . $item_map->{$TicketObj->Id}{prev} if $item_map->{$TicketObj->Id}{prev};
     $link_rel{next}  = "Ticket/Display.html?id=" . $item_map->{$TicketObj->Id}{next} if $item_map->{$TicketObj->Id}{next};
-    $link_rel{last}  = "Ticket/Display.html?id=" . $item_map->{last}                 if $item_map->{$TicketObj->Id}{next};
+    $link_rel{last}  = "Ticket/Display.html?id=" . $item_map->{last}                 if $item_map->{$TicketObj->Id}{next} && $item_map->{last};
 }
 </%INIT>