%# BEGIN BPS TAGGED BLOCK {{{ %# %# COPYRIGHT: %# %# This software is Copyright (c) 1996-2020 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-investigation') }", &> <& /Elements/Tabs &> % $m->callback(CallbackName => 'BeforeActionList', %ARGS, Actions => \@results, ARGSRef => \%ARGS, Ticket => $SplitObj); <& /Elements/ListActions, actions => \@results &> <%PERL> if ( $SplitObj && $SplitObj->id && !$SplitObj->CurrentUserHasRight('ModifyTicket') ) { $m->out( loc('You are not allowed to split from #[_1].', $SplitObj->id ) ); return; } if ( $ChildObj && $ChildObj->id && !$ChildObj->CurrentUserHasRight('ModifyTicket') ) { $m->out( loc('You are not allowed to link with #[_1].', $ChildObj->id ) ); return; } % if ( $Split ) {
% } else { % } % if ( $ChildObj ) { % } % if ( $Split ) { % } % $m->callback( CallbackName => 'AfterHidden', ARGSRef => \%ARGS ); <& /Elements/Crypt/SignEncryptWidget:ShowIssues, self => $gnupg_widget &>
<&| /Widgets/TitleBox, title => 'Basics', class => 'ticket-info-basics' &> % if ($constituency) {
<% loc('Constituency') %>:
<% $constituency %>
% } % if ( $Split ) { % } % if ( $ChildObj ) { % }
<&|/l&>Queue:
<& /RTIR/Elements/SelectRTIRQueue, Name => "Queue", Default => $queue, AutoSubmit => 1, ShowNullOption => 0, LimitToConstituency => $limit_to_constituency, Constituency => $constituency &>
<&|/l&>Status:
<& /Ticket/Elements/SelectStatus, Name => 'Status', Object => $QueueObj, DefaultValue => 0, Default => $ARGS{Status} || $QueueObj->LifecycleObj->DefaultOnCreate, Statuses => [ RT::IR->Statuses( Lifecycle => RT::IR->lifecycle_incident ) ], &>
<&|/l&>Owner:
% if ( $ChildObj ) {
<& /Elements/ShowUser, User => $ChildObj->OwnerObj &>
% } else {
<& /Elements/SelectOwner, Name => 'Owner', QueueObj => $QueueObj, Default => $ARGS{'Owner'} || $session{'CurrentUser'}->Id &>
% }
% if ( !$QueueObj->SLADisabled ) {
<&|/l&>SLA:
<& /Elements/SelectSLA, Name => 'SLA', Default => $ARGS{SLA} || RT::SLA->GetDefaultServiceLevel(Queue => $QueueObj), DefaultValue => RT::SLA->GetDefaultServiceLevel(Queue => $QueueObj) ? 0 : 1, QueueObj => $QueueObj, &>
% } <& /RTIR/Elements/EditCustomFields, %ARGS, TicketObj => $ticket, QueueObj => $QueueObj, DefaultsFrom => $SplitObj || $ChildObj, CFDefaults => \%CFDefaults, &> <& /Elements/EditCustomFieldCustomGroupings, %ARGS, %CFDefaults, Object => $ticket, CustomFieldGenerator => sub { $QueueObj->TicketCustomFields }, Groupings => [ RT::CustomField->CustomGroupings('RTIR::Ticket'), '' ], &>
<&| /Widgets/TitleBox, title => $Title, class => 'ticket-info-message' &>
<&|/l&>Subject:
% if ( $gnupg_widget ) {
 
<& /Elements/Crypt/SignEncryptWidget, self => $gnupg_widget, QueueObj => $QueueObj &>
% }
<& /Elements/MessageBox, Default => $ARGS{'Content'}, IncludeSignature => 0, &>
<& /Ticket/Elements/AddAttachments, %ARGS, QueueObj => $QueueObj &> <&| /Widgets/TitleBox, title => loc('Details'), class => 'ticket-info-details' &> <& /Ticket/Elements/EditBasics, InTable => 0, QueueObj => $QueueObj, fields => [ { name => 'Priority', comp => '/Elements/SelectPriority', args => { Name => 'InitialPriority', QueueObj => $QueueObj, Default => defined $ARGS{'InitialPriority'} && length $ARGS{'InitialPriority'} ? $ARGS{'InitialPriority'} : $QueueObj->DefaultValue('InitialPriority') , }, }, { name => 'Final Priority', comp => '/Elements/SelectPriority', args => { Name => 'FinalPriority', QueueObj => $QueueObj, Default => defined $ARGS{'FinalPriority'} && length $ARGS{'FinalPriority'} ? $ARGS{'FinalPriority'} : $QueueObj->DefaultValue('FinalPriority') , }, }, { name => 'Time Worked', comp => '/Elements/EditTimeValue', args => { Name => "TimeWorked", Default => $ARGS{'TimeWorked'} || '', }, }, { name => 'Time Left', comp => '/Elements/EditTimeValue', args => { Name => "TimeLeft", Default => $ARGS{'TimeLeft'} || '', }, }, { name => 'Starts', comp => '/Elements/SelectDate', args => { Name => 'Starts', Default => $ARGS{'Starts'} || '', }, }, { name => 'Due', comp => '/Elements/SelectDate', args => { Name => 'Due', Default => $ARGS{'Due'} || '', }, }, ], &>
<& /Elements/Submit, Name => 'CreateIncident', Label => $SubmitLabel, SubmitId => 'create-ticket' &>
<& /RTIR/Investigation/Elements/Create, %ARGS, NamePrefix => 'Investigation', QueueObj => $InvestigationsQueueObj, Lifecycle => RT::IR->lifecycle_investigation, Constituency => $constituency, SkipField => { Owner => 1, Attachments => 1, DateFields => 1 }, IncludeSignature => (exists $ARGS{'InvestigationContent'} ? 0 : 1), &>
% $m->callback( CallbackName => 'FormEnd', QueueObj => $QueueObj, Constituency => $constituency, % ChildObj => $ChildObj, SplitObj => $SplitObj, ARGSRef => \%ARGS );
<%INIT> my %CFDefaults; $m->callback( CallbackName => 'Init', CallbackPage => '/Ticket/Create.html', ARGSRef => \%ARGS, ); my @results; # if there isn't a subject, but there is a child, use that one my $ChildObj; if ( $Child ) { $ChildObj = LoadTicket( $Child ); $Child = $ARGS{'Child'} = $ChildObj->id; $ARGS{'Subject'} ||= $ChildObj->Subject; } my $SplitObj; if ( $Split ) { $SplitObj = LoadTicket( $Split ); $Split = $ARGS{'Split'} = $SplitObj->id; } $m->callback( CallbackName => 'ProcessArguments', ARGSRef => \%ARGS, Ticket => $SplitObj, Child => $ChildObj, CreateIncident => \$CreateIncident ); my $constituency = $m->{'RTIR_ConstituencyFilter'} || ''; for my $related_ticket ($ChildObj, $SplitObj) { next if !$related_ticket; my $related_constituency = RT::IR->ConstituencyFor($related_ticket); if ($constituency && $constituency ne $related_constituency) { push @results, loc("[_1] constituency '[_2]' does not match current constituency '[_3]'", RT::IR::TicketType(Ticket=>$related_ticket), $related_constituency, $constituency); } elsif(!$constituency) { $constituency = $related_constituency; } last; } my $limit_to_constituency = # Limit no matter what if we have a filter $m->{'RTIR_ConstituencyFilter'} || # Also limit if we have a linked constituency and StrictConstituencyLinking is set (RT::IR->StrictConstituencyLinking && $constituency) ? 1 : 0; # Load the first Incident queue if none is provided my $queue = $ARGS{'Queue'}; unless ( $queue ) { my $queues = RT::Queues->new($session{'CurrentUser'}); $queues->Limit( FIELD => 'Lifecycle', OPERATOR => '=', VALUE => RT::IR->lifecycle_incident, ); while (my $object = $queues->Next) { # Ensure the user can CreateTicket in the queue. next unless $session{CurrentUser}->HasRight( Object => $object, Right => 'CreateTicket' ); $queue = $object->Id; last; } } my $QueueObj = RT::Queue->new($session{'CurrentUser'}); $QueueObj->Load( $queue ); if (!$QueueObj->Name) { Abort( loc("Queue '[_1]' could not be loaded.", $queue) ); } # Load appropriate Investigations queue my $InvestigationsQueue = $ARGS{InvestigationQueue} || 'Investigations' . ( $constituency ? ' - ' . $constituency : '' ); my $InvestigationsQueueObj = RT::Queue->new( $session{'CurrentUser'} ); $InvestigationsQueueObj->Load( $InvestigationsQueue ); # Users limited by constituency may not be able to use the default or specified investigations queue # Look up what queue the user has SeeQueue and CreateTicket for and use that instead. unless ( $InvestigationsQueueObj->Name ) { RT->Logger->debug( "Investigation Queue '$InvestigationsQueue' could not be loaded for user " . $session{'CurrentUser'}->Id . "." ); my $investigation_queues = RT::Queues->new($session{'CurrentUser'}); $investigation_queues->Limit( FIELD => 'Lifecycle', OPERATOR => '=', VALUE => RT::IR->lifecycle_investigation, ); while (my $object = $investigation_queues->Next) { # Ensure the user can CreateTicket in the queue next unless $session{CurrentUser}->HasRight( Object => $object, Right => 'CreateTicket' ); $InvestigationsQueueObj = $object; last; } } if( !RT::IR->IsIncidentQueue($QueueObj) ) { RT::Interface::Web::Redirect(RT::IR->HREFTo( '/Create.html?' . $m->comp('/Elements/QueryString', %ARGS ))); } my $ticket = RT::Ticket->new($session{'CurrentUser'}); # empty ticket object ProcessAttachments(ARGSRef => \%ARGS); my $checks_failure = 0; my $gnupg_widget = $m->comp( '/Elements/Crypt/SignEncryptWidget:new', Arguments => \%ARGS ); $m->comp( '/Elements/Crypt/SignEncryptWidget:Process', self => $gnupg_widget, QueueObj => $QueueObj, ); if ( $CreateIncident && $gnupg_widget ) { my $status = $m->comp('/Elements/Crypt/SignEncryptWidget:Check', self => $gnupg_widget, Operation => 'Create', QueueObj => $QueueObj, ); $checks_failure = 1 unless $status; } if ( $CreateIncident ) { my $TicketCFs = $QueueObj->TicketCustomFields; my ($status, @msg) = $m->comp('/Elements/ValidateCustomFields', CustomFields => $TicketCFs, ARGSRef => \%ARGS, ); unless ( $status ) { push @results, loc( "Invalid value(s) of the custom fields:" ); while (my $CF = $TicketCFs->Next) { my $msg = $m->notes('InvalidField-' . $CF->Id) or next; push @results, $CF->Name . ': ' . $msg; } $checks_failure = 1; } $checks_failure += RT::IR->FilterRTAddresses( ARGSRef => \%ARGS, Fields => { Requestors => 'Requestor', Cc => 'Cc', AdminCc => 'AdminCc' }, results => \@results, ); } if ( $CreateWithInvestigation ) { $checks_failure += RT::IR->FilterRTAddresses( ARGSRef => \%ARGS, Fields => { InvestigationRequestors => 'Requestor', InvestigationCc => 'Cc', InvestigationAdminCc => 'AdminCc', }, results => \@results, ); } if ( $CreateWithInvestigation && !$InvestigationRequestors ) { push @results, loc( "You must enter a correspondent for the investigation" ); $checks_failure = 1; } $m->callback( CallbackName => 'BeforeCreateRedirect', ARGSRef => \%ARGS, Child => $ChildObj, results => \@results, checks_failure => \$checks_failure ); if ( !$checks_failure && $CreateIncident ) { my ($inc_obj, @tmp) = $m->comp( '/RTIR/Investigation/Elements/Create:Process', %ARGS, $Child? ('MemberOf-new' => $Child): (), NamePrefix => '', DefaultsNamePrefix => '', ); push @results, @tmp; if( $inc_obj ) { my $inv_obj; if ( $CreateWithInvestigation ) { my (@tmp); ($inv_obj, @tmp) = $m->comp( '/RTIR/Investigation/Elements/Create:Process', %ARGS, NamePrefix => 'Investigation', DefaultsNamePrefix => '', ); push @results, @tmp; if ( $inv_obj ) { my($id, $msg) = $inv_obj->AddLink( Type => 'MemberOf', Target => $inc_obj->id ); #XXX: correct message on success push @results, $msg if !$id || $msg; } } $m->callback(CallbackName => 'BeforeDisplay', ARGSRef => \%ARGS, Child => $ChildObj, TicketObj => $inc_obj, results => \@results ); MaybeRedirectForResults( Actions => \@results, Path => RT::IR->HREFTo("Incident/Display.html", IncludeWebPath => 0), Arguments => { id => $inc_obj->id }, ); } } my $SubmitLabel; if ( $Split ) { $SubmitLabel = loc('Split'); } else { $SubmitLabel = loc('Create'); } unless ( exists $ARGS{'Content'} ) { my $Transactions; if ( $SplitObj ) { $Transactions = $SplitObj->Transactions; } elsif ( $ChildObj ) { $Transactions = $ChildObj->Transactions; } if ( $Transactions ) { $ARGS{'Content'} = $m->scomp("/RTIR/Elements/TransactionData", Transactions => $Transactions, Type => 'messages', Include => ['Create', 'Correspond'], ) || ''; $ARGS{'Content'} =~ s/\>/>/g; } } <%ARGS> $Title => loc("Create a new Incident") $QuoteTransaction => undef $CreateWithInvestigation => 0 $CreateIncident => $CreateWithInvestigation $InvestigationRequestors => 0 $Split => undef $Child => undef