%# BEGIN BPS TAGGED BLOCK {{{ %# %# COPYRIGHT: %# %# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (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 }}} <& /RTIR/Elements/Header, Title => $Title, onload => "function () { hide('Ticket-Create-details') }", &> <& /Elements/Tabs &> % $m->callback(CallbackName => 'BeforeActionList', %ARGS, Actions => \@results, ARGSRef => \%ARGS, Ticket => $SplitObj); <& /Elements/ListActions, actions => \@results &> % if ( $Split && !$SplitObj->CurrentUserHasRight('ModifyTicket') ) { <% loc("You are not allowed to split this [_1].", $name) %> % $m->abort(); % } % unless ( $Split ) {
% } else { % } % if ( $Split ) { % } % if ( $gnupg_widget ) { <& /Elements/GnuPG/SignEncryptWidget:ShowIssues, self => $gnupg_widget &> % }
<&| /Widgets/TitleBox, title => loc("Basics"), class=>'ticket-info-basics' &> % if ( $SplitObj ) { % } <& /RTIR/Elements/SelectIncident, Type => $Type, Default => \@Incident, SplitObj => $SplitObj, &> <& /Ticket/Elements/EditBasics, InTable => 1, fields => [ { name => 'Status', comp => '/Elements/SelectStatus', args => { Name => "Status", Default => $ARGS{Status} || $QueueObj->Lifecycle->DefaultOnCreate, DefaultValue => 0, SkipDeleted => 1, QueueObj => $QueueObj, }, }, { name => 'Owner', comp => '/Elements/SelectOwner', args => { Name => "Owner", Default => $ARGS{Owner} || $session{'CurrentUser'}->id || RT->Nobody->Id, DefaultValue => 0, QueueObj => $QueueObj, }, }, ], &> % if ( $constituency_cf ) { % } <& /RTIR/Elements/EditCustomFields, %ARGS, TicketOnj => undef, QueueObj => $QueueObj, DefaultsFrom => $SplitObj || $IncidentObj[0], &> <& /Ticket/Elements/EditTransactionCustomFields, %ARGS, QueueObj => $QueueObj, InTable => 1, &>
<&|/l&>Split from: <% $SplitObj->id %>
<&|/l&>Constituency: % if ( !$Incident[0] || RT->Config->Get('_RTIR_Constituency_Propagation') eq 'no' ) { <& /RTIR/Elements/EditRTIRField, QueueObj => $QueueObj, Name => 'Constituency', ($Incident[0] ? (PropagationObject => $IncidentObj[0]) : ()), &> % } else { % #TODO: hacks, we need way to define CF value on Create, but don't allow user to change it <& /RTIR/Elements/ShowRTIRField, Ticket => $IncidentObj[0], Name => 'Constituency' &> % }
<&| /Widgets/TitleBox, title => $Title, class => 'messagedetails' &> % $m->callback( CallbackName => 'AfterRequestors', ARGSRef => \%ARGS ); % if ( $gnupg_widget ) { % } <& /Ticket/Elements/AddAttachments, %ARGS, QueueObj => $QueueObj &>
<&|/l&>Correspondents: <& /Elements/EmailInput, Name => 'Requestors', Default => $ARGS{'Requestors'}, Size => undef, &>
  /> <&|/l&>Don't send any emails to correspondents.
<&|/l&>Cc: <& /Elements/EmailInput, Name => 'Cc', Default => $ARGS{'Cc'}, Size => undef, &>
  <&|/l&>(Sends a carbon-copy of this update to a comma-delimited list of email addresses. These people will receive future updates.)
<&|/l&>Admin Cc: <& /Elements/EmailInput, Name => 'AdminCc', Default => $ARGS{'AdminCc'}, Size => undef, &>
  <&|/l&>(Sends a carbon-copy of this update to a comma-delimited list of administrative email addresses. These people will receive future updates.)
<&|/l&>Subject:
  <& /Elements/GnuPG/SignEncryptWidget, self => $gnupg_widget, QueueObj => $QueueObj &>
<&|/l&>Message: % my $include_signature = 1; % unless (exists $ARGS{Content}) { % my $Transactions; % if ($SplitObj) { % $Transactions = $SplitObj->Transactions; % } elsif (@IncidentObj) { % $Transactions = $IncidentObj[0]->Transactions; % } % % if ($Transactions) { % # Investigations should quote their included text % my $quote = 0; % if ($Type eq 'Investigation') { % $quote = 1; % } % $ARGS{Content} = $m->scomp("/RTIR/Elements/TransactionData", % Transactions => $Transactions, % Type => 'messages', % Include => {'Create', 'Correspond'}, % QuoteText => $quote); % $ARGS{Content} =~ s/\>/>/g if $ARGS{Content}; % } % } else { % $include_signature = 0; % } % if ( RT->Config->Get('ArticleOnTicketCreate')) { <& /Articles/Elements/BeforeMessageBox, %ARGS, QueueObj => $QueueObj &> % } % $m->callback( %ARGS, CallbackPage => '/Ticket/Create.html', CallbackName => 'BeforeMessageBox' ); % if ( $ARGS{Content} ) { <& /Elements/MessageBox, Default => $ARGS{Content}, IncludeSignature => $include_signature &> % } else { <& /Elements/MessageBox, QuoteTransaction => $QuoteTransaction &> % }
<& /Elements/Submit, Name => "Create", Label => $SubmitCaption &>
<&| /Widgets/TitleBox, title => loc("Dates"), class=>'ticket-info-dates' &> <& /Ticket/Elements/EditBasics, InTable => 1, fields => [ { name => 'Starts', comp => '/Elements/SelectDate', args => { Name => 'Starts', Default => $ARGS{'Starts'} || '' }, }, { name => 'Due', comp => '/Elements/SelectDate', args => { Name => 'Due', Default => $ARGS{'Due'} || '' }, }, ], &>
<&| /Widgets/TitleBox, title => loc("Time"), class=>'ticket-info-time' &> <& /Ticket/Elements/EditBasics, InTable => 1, fields => [ { name => 'Time Estimated', comp => '/Elements/EditTimeValue', args => { Name => "TimeEstimated", Default => $ARGS{'TimeEstimated'} || '', }, }, { name => 'Time Worked', comp => '/Elements/EditTimeValue', args => { Name => "TimeWorked", Default => $ARGS{'TimeWorked'} || '', }, }, { name => 'Time Left', comp => '/Elements/EditTimeValue', args => { Name => "TimeLeft", Default => $ARGS{'TimeLeft'} || '', }, }, ], &>
% if ( $Type eq "Investigation" && @IncidentObj ) { <& /RTIR/Elements/AttachReports, Ticket => \@IncidentObj &> % }
<%INIT> $m->callback( CallbackName => 'Init', CallbackPage => '/Ticket/Create.html', ARGSRef => \%ARGS, ); my $QueueObj = RT::Queue->new( $session{'CurrentUser'} ); $QueueObj->Load( $Queue ) || Abort( loc("Queue could not be loaded.") ); my $Type = RT::IR::TicketType( Queue => $Queue ); if ($Type eq 'Block' && RT->Config->Get('RTIR_DisableBlocksQueue') ) { Abort(loc("Blocks queue is disabled via config file")); } if ( $m->comp_exists("/RTIR/$Type/Create.html") ) { return $m->comp( "/RTIR/$Type/Create.html", %ARGS ); } my ($name); if ( $Type eq 'Report' ) { $name = 'Incident Report'; } $name ||= $Type; my (@results, $checks_failure, $skip_create); $skip_create = !$ARGS{'Create'}; my $constituency_cf = RT::IR->CustomFields( 'Constituency', Queue => $Queue ); my $constituency_field; $constituency_field = 'Object-RT::Ticket--CustomField-' . $constituency_cf->id .'-Values' if $constituency_cf; my $SplitObj; if ( $Split ) { $SplitObj = LoadTicket( $Split ); $ARGS{'Split'} = $Split = $SplitObj->id; unless (@Incident) { @Incident = map $_->id, @{ RT::IR->Incidents( $SplitObj )->ItemsArrayRef || [] }; $DECODED_ARGS->{Incident} = \@Incident; } } my @IncidentObj; foreach my $id ( grep $_, @Incident ) { my $error = 1; my $inc = RT::Ticket->new( $session{'CurrentUser'} ); $inc->Load( $id ); unless ( $inc->id ) { push @results, loc("Couldn't load incident #[_1]", $id ); } elsif ( $inc->QueueObj->Name ne 'Incidents' ) { push @results, loc('Ticket #[_1] is not an Incident', $id ); } elsif ( !$skip_create && $constituency_field && RT->Config->Get('_RTIR_Constituency_Propagation') eq 'reject' && lc $ARGS{$constituency_field} ne lc $inc->FirstCustomFieldValue('Constituency') ) { push @results, loc('Incident #[_1] has constituency [_2], choose the same value for a new ticket or use another Incident', $id, $inc->FirstCustomFieldValue('Constituency') ); } else { push @IncidentObj, $inc; $error = 0; } $checks_failure += $error; } @Incident = map $_->id, @IncidentObj; my $children_config = RT->Config->Get('RTIR_IncidentChildren')->{ $Type }; if ( @Incident > 1 && !$children_config->{'Multiple'} ) { push @{ $m->{'request_args'} }, Incident => $Incident[-1]; @Incident = ($Incident[-1]); } $Subject ||= $IncidentObj[0]->Subject if @IncidentObj; push @results, $m->comp( 'SELF:ProcessAttachments', %ARGS ); my $gnupg_widget = $m->comp('/Elements/GnuPG/SignEncryptWidget:new', Arguments => \%ARGS ); $m->comp( '/Elements/GnuPG/SignEncryptWidget:Process', self => $gnupg_widget, QueueObj => $QueueObj, ); if ( !$skip_create && $gnupg_widget ) { my $status = $m->comp('/Elements/GnuPG/SignEncryptWidget:Check', self => $gnupg_widget, Operation => 'Create', QueueObj => $QueueObj, ); $checks_failure = 1 unless $status; } unless ( $skip_create ) { if ( $Type eq 'Investigation' && !$ARGS{'Requestors'} ) { push @results, loc( "You must enter a correspondent" ); $checks_failure = 1; } if ( $children_config->{'Required'} && !@IncidentObj ) { push @results, loc( "You must enter an Incident ID" ); $checks_failure = 1; } } unless ( $skip_create ) { my $ticket_status = $m->comp('/Elements/ValidateCustomFields', CustomFields => $QueueObj->TicketCustomFields,, ARGSRef => \%ARGS, ); my $txn_status = $m->comp('/Elements/ValidateCustomFields', CustomFields => $QueueObj->TicketTransactionCustomFields, ARGSRef => \%ARGS, NamePrefix => "Object-RT::Transaction--CustomField-", ); unless ( $ticket_status && $txn_status ) { push @results, loc( "Invalid value(s) of the custom fields" ); $checks_failure = 1; } } unless ( $skip_create ) { $checks_failure += RT::IR->FilterRTAddresses( ARGSRef => \%ARGS, Fields => { Requestors => 'Requestor', Cc => 'Cc', AdminCc => 'AdminCc' }, results => \@results, ); } # for articles and other things $m->callback( CallbackName => 'BeforeCreate', CallbackPage => '/Ticket/Create.html', ARGSRef => \%ARGS, results => \@results, skip_create => \$skip_create, checks_failure => $checks_failure ); unless ( $skip_create || $checks_failure ) { $ARGS{'new-MemberOf'} = join ' ', @Incident; $m->callback(CallbackName => 'BeforeDisplay', Ticket => $SplitObj, ARGSRef => \%ARGS); push @{ $session{'Actions'}{''} ||= [] }, @results; return $m->comp( 'Display.html', %ARGS, SkipNotification => \@SkipNotification ); } unshift @results, loc("Creation failed:") if $checks_failure && @results; my ($Title, $SubmitCaption); if ( $Split ) { $Title = loc("Split [_1] #[_2]: [_3]", $name, $SplitObj->id, $SplitObj->Subject); $SubmitCaption = loc("Split"); } else { if ( $Type eq 'Investigation' ) { $Title = loc("Launch a new [_1]", $name); $SubmitCaption = loc("Launch"); } else { $Title = loc("Create a new [_1]", $name); $SubmitCaption = loc("Create"); } } PageMenu->child( basics => raw_html => q[] . loc('Basics') . q[]); PageMenu->child( details => raw_html => q[] . loc('Details') . q[]); <%ARGS> $Queue => undef @SkipNotification => () $Subject => undef $QuoteTransaction => undef # Parent Incident(s) @Incident => () $Split => undef <%METHOD ProcessAttachments> <%ARGS> @DeleteAttachments => () $Attachment => ''; <%INIT> my @results; # deal with deleting uploaded attachments foreach ( grep $_ && exists $session{'Attachments'}{ $_ }, @DeleteAttachments, map { /^DeleteAttach-(.*)$/; $1 } keys %ARGS, ) { delete $session{'Attachments'}{ $_ }; push @results, loc("Deleted attachment '[_1]'", $_ ); $session{'i'}++; } # store the uploaded attachment in session foreach my $field ( 'Attach', 'Attachment' ) { next unless $ARGS{ $field }; my $filename = "$ARGS{ $field }"; $filename =~ s{^.*[\\/]}{}; my $entity = MakeMIMEEntity( AttachmentFieldName => $field, ); $session{'Attachments'}{ $filename } = $entity; push @results, loc("Added attachment '[_1]'", $filename ); $session{'i'}++; } delete $session{'Attachments'} if $session{'Attachments'} && !%{ $session{'Attachments'} }; return @results;