1 %# BEGIN BPS TAGGED BLOCK {{{
5 %# This software is Copyright (c) 1996-2015 Best Practical Solutions, LLC
6 %# <sales@bestpractical.com>
8 %# (Except where explicitly superseded by other copyright notices)
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
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.
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.
30 %# CONTRIBUTION SUBMISSION POLICY:
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.)
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.
47 %# END BPS TAGGED BLOCK }}}
50 LinkRel => \%link_rel &>
53 % $m->callback(CallbackName => 'BeforeActionList', %ARGS, Actions => \@Actions, ARGSRef => \%ARGS, Ticket => $TicketObj);
55 <& /Elements/ListActions, actions => \@Actions &>
56 <& Elements/ShowUpdateStatus, Ticket => $TicketObj &>
57 <& Elements/ShowDependencyStatus, Ticket => $TicketObj &>
59 % $m->callback( %ARGS, Ticket => $TicketObj, Transactions => $transactions, Attachments => $attachments, CallbackName => 'BeforeShowSummary' );
61 <&| /Widgets/TitleBox, title => loc('Ticket metadata') &>
62 <& /Ticket/Elements/ShowSummary, Ticket => $TicketObj, Attachments => $attachments &>
67 % $m->callback( Ticket => $TicketObj, %ARGS, Transactions => $transactions, Attachments => $attachments, CallbackName => 'BeforeShowHistory' );
69 % my $ShowHistory = RT->Config->Get("ShowHistory", $session{'CurrentUser'});
70 % if ($ShowHistory eq "delay") {
71 <& /Ticket/Elements/DelayShowHistory,
73 ShowHeaders => $ARGS{'ShowHeaders'},
75 % } elsif (not $ForceShowHistory and $ShowHistory eq "click") {
76 <& /Ticket/Elements/ClickToShowHistory,
78 ShowHeaders => $ARGS{'ShowHeaders'},
81 <& /Elements/ShowHistory ,
83 Transactions => $transactions,
84 ShowHeaders => $ARGS{'ShowHeaders'},
85 Attachments => $attachments,
86 AttachmentContent => $attachment_content
90 % $m->callback( %ARGS,
91 % Ticket => $TicketObj,
92 % Transactions => $transactions,
93 % Attachments => $attachments,
94 % CallbackName => 'AfterShowHistory',
101 $ForceShowHistory => 0
102 $RedirectToBasics => 0
107 $m->callback( TicketObj => $TicketObj, ARGSRef => \%ARGS, CallbackName => 'Initial' );
109 if ( ! $ARGS{'NoRedirect'} && RT::Interface::Web->MobileClient()) {
110 $id ||= $TicketObj->id if $TicketObj;
111 RT::Interface::Web::Redirect(RT->Config->Get('WebURL').'m/ticket/show?id='.$id);
116 my (@Actions, $title);
119 unless ($id || $TicketObj) {
120 Abort('No ticket specified');
123 if ($ARGS{'id'} eq 'new') {
124 # Create a new ticket
126 # Massage customer IDs into member links.
127 my @cust_uris = map {
128 /^(\d+)$/ && "freeside://freeside/cust_main/$1"
129 } split(' ', $ARGS{'new-Customer'});
131 $ARGS{'new-MemberOf'} =
132 join(' ', $ARGS{'new-MemberOf'}, @cust_uris);
134 my $Queue = RT::Queue->new( $session{'CurrentUser'} );
135 $Queue->Load($ARGS{'Queue'});
136 unless ( $Queue->id ) {
137 Abort('Queue not found');
140 unless ( $Queue->CurrentUserHasRight('CreateTicket') ) {
141 Abort('You have no permission to create tickets in that queue.');
144 ($TicketObj, @Actions) = CreateTicket( %ARGS );
145 unless ( $TicketObj->CurrentUserHasRight('ShowTicket') ) {
146 Abort("No permission to view newly created ticket #".$TicketObj->id.".");
149 $TicketObj ||= LoadTicket($ARGS{'id'});
151 $TicketObj->CurrentUser->PrincipalObj->HasRights( Object => $TicketObj );
155 $m->callback( CallbackName => 'BeforeProcessArguments',
156 TicketObj => $TicketObj,
157 ActionsRef => \@Actions, ARGSRef => \%ARGS,
158 SkipProcessing => \$SkipProcessing );
160 if ( !$SkipProcessing ) {
161 if ( defined $ARGS{'Action'} ) {
162 if ($ARGS{'Action'} =~ /^(Steal|Delete|Take|SetTold)$/) {
164 my ($res, $msg) = $TicketObj->$action();
165 push(@Actions, $msg);
169 $m->callback(CallbackName => 'ProcessArguments',
170 Ticket => $TicketObj,
172 Actions => \@Actions);
174 push @Actions, ProcessUpdateMessage(
176 Actions => \@Actions,
177 TicketObj => $TicketObj,
180 #Process status updates
181 push @Actions, ProcessTicketWatchers(ARGSRef => \%ARGS, TicketObj => $TicketObj );
182 push @Actions, ProcessTicketBasics( ARGSRef => \%ARGS, TicketObj => $TicketObj );
183 push @Actions, ProcessTicketLinks( ARGSRef => \%ARGS, TicketObj => $TicketObj );
184 push @Actions, ProcessTicketDates( ARGSRef => \%ARGS, TicketObj => $TicketObj );
185 push @Actions, ProcessObjectCustomFieldUpdates(ARGSRef => \%ARGS, TicketObj => $TicketObj );
186 # If this fails due to required fields being empty, it will set
187 # notes('RedirectToBasics').
188 push @Actions, ProcessTicketStatus( ARGSRef => \%ARGS, TicketObj => $TicketObj );
190 push @Actions, ProcessTicketReminders( ARGSRef => \%ARGS, TicketObj => $TicketObj );
192 unless ($TicketObj->CurrentUserHasRight('ShowTicket')) {
194 Abort("A change was applied successfully, but you no longer have permissions to view the ticket", Actions => \@Actions);
196 Abort("No permission to view ticket");
199 if ( $ARGS{'MarkAsSeen'} ) {
200 $TicketObj->SetAttribute(
201 Name => 'User-'. $TicketObj->CurrentUser->id .'-SeenUpTo',
202 Content => $TicketObj->LastUpdated,
204 push @Actions, loc('Marked all messages as seen');
210 $title = loc("Ticket #[_1]: [_2]", $TicketObj->Id, $TicketObj->Subject || '');
213 CallbackName => 'BeforeDisplay',
214 TicketObj => \$TicketObj,
215 Actions => \@Actions,
220 # This code does automatic redirection if any updates happen.
221 $m->notes('RedirectToBasics' => 1) if $RedirectToBasics;
222 my $path = '/Ticket/'. ( $m->notes('RedirectToBasics') ? 'Modify.html'
224 MaybeRedirectForResults(
225 Actions => \@Actions,
226 $TicketObj->Type eq 'approval' && RT->Config->Get('ForceApprovalsView')
227 ? (Path => "/Approvals/Display.html", Force => 1)
230 Anchor => $ARGS{'Anchor'},
231 Arguments => { id => $TicketObj->id },
234 my $transactions = $TicketObj->SortedTransactions;
235 my $attachments = $TicketObj->Attachments;
236 my $attachment_content = $TicketObj->TextAttachments;
239 if (defined $session{'tickets'} and ($ARGS{'Query'} or $session{'CurrentSearchHash'}->{'Query'})) {
240 my $item_map = $session{'tickets'}->ItemMap;
241 $link_rel{first} = "Ticket/Display.html?id=" . $item_map->{first} if $item_map->{$TicketObj->Id}{prev};
242 $link_rel{prev} = "Ticket/Display.html?id=" . $item_map->{$TicketObj->Id}{prev} if $item_map->{$TicketObj->Id}{prev};
243 $link_rel{next} = "Ticket/Display.html?id=" . $item_map->{$TicketObj->Id}{next} if $item_map->{$TicketObj->Id}{next};
244 $link_rel{last} = "Ticket/Display.html?id=" . $item_map->{last} if $item_map->{$TicketObj->Id}{next} && $item_map->{last};