2 $QuoteTransaction => undef
6 $m->callback( CallbackName => "Init", ARGSRef => \%ARGS );
7 my $Queue = $ARGS{Queue};
9 my $escape = sub { $m->interp->apply_escapes(shift, 'h') };
15 my $key = shift @pairs;
16 my $val = shift @pairs;
18 $m->out("<div class=\"entry\"><span class=\"label\">$key</span><div class=\"value\">$val</div></div>");
27 $CloneTicketObj = RT::Ticket->new( $session{CurrentUser} );
28 $CloneTicketObj->Load($CloneTicket)
29 or Abort( loc("Ticket could not be loaded") );
32 Requestors => join( ',', $CloneTicketObj->RequestorAddresses ),
33 Cc => join( ',', $CloneTicketObj->CcAddresses ),
34 AdminCc => join( ',', $CloneTicketObj->AdminCcAddresses ),
35 InitialPriority => $CloneTicketObj->Priority,
38 $clone->{$_} = $CloneTicketObj->$_()
39 for qw/Owner Subject FinalPriority TimeEstimated TimeWorked
42 $clone->{$_} = $CloneTicketObj->$_->AsString
43 for grep { $CloneTicketObj->$_->Unix }
44 map { $_ . "Obj" } qw/Starts Started Due Resolved/;
46 my $members = $CloneTicketObj->Members;
47 my ( @members, @members_of, @refers, @refers_by, @depends, @depends_by );
48 my $refers = $CloneTicketObj->RefersTo;
49 my $get_link_value = sub {
50 my ($link, $type) = @_;
51 my $uri_method = $type . 'URI';
52 my $local_method = 'Local' . $type;
53 my $uri = $link->$uri_method;
54 return if $uri->IsLocal and
56 $uri->Object->isa('RT::Ticket') and
57 $uri->Object->Type eq 'reminder';
59 return $link->$local_method || $uri->URI;
61 while ( my $refer = $refers->Next ) {
62 my $refer_value = $get_link_value->($refer, 'Target');
63 push @refers, $refer_value if defined $refer_value;
65 $clone->{'new-RefersTo'} = join ' ', @refers;
67 my $refers_by = $CloneTicketObj->ReferredToBy;
68 while ( my $refer_by = $refers_by->Next ) {
69 my $refer_by_value = $get_link_value->($refer_by, 'Base');
70 push @refers_by, $refer_by_value if defined $refer_by_value;
72 $clone->{'RefersTo-new'} = join ' ', @refers_by;
74 my $cfs = $CloneTicketObj->QueueObj->TicketCustomFields();
75 while ( my $cf = $cfs->Next ) {
77 my $cf_values = $CloneTicketObj->CustomFieldValues( $cf->id );
79 while ( my $cf_value = $cf_values->Next ) {
80 push @cf_values, $cf_value->Content;
82 $clone->{"Object-RT::Ticket--CustomField-$cf_id-Value"} = join "\n",
86 for ( keys %$clone ) {
87 $ARGS{$_} = $clone->{$_} if not defined $ARGS{$_};
94 my $title = loc("Create a ticket");
96 my $QueueObj = new RT::Queue($session{'CurrentUser'});
97 $QueueObj->Load($Queue) || Abort(loc("Queue could not be loaded."));
99 $m->callback( QueueObj => $QueueObj, title => \$title, results => \@results, ARGSRef => \%ARGS );
101 $QueueObj->Disabled && Abort(loc("Cannot create tickets in a disabled queue."));
103 my $CFs = $QueueObj->TicketCustomFields();
105 my $ValidCFs = $m->comp(
106 '/Elements/ValidateCustomFields',
107 CustomFields => $CFs,
111 # {{{ deal with deleting uploaded attachments
112 foreach my $key (keys %ARGS) {
113 if ($key =~ m/^DeleteAttach-(.+)$/) {
114 delete $session{'Attachments'}{$1};
116 $session{'Attachments'} = { %{$session{'Attachments'} || {}} };
120 # {{{ store the uploaded attachment in session
121 if ($ARGS{'Attach'}) { # attachment?
122 my $attachment = MakeMIMEEntity(
123 AttachmentFieldName => 'Attach'
126 my $file_path = Encode::decode_utf8("$ARGS{'Attach'}");
127 $session{'Attachments'} = {
128 %{$session{'Attachments'} || {}},
129 $file_path => $attachment,
134 # delete temporary storage entry to make WebUI clean
135 unless (keys %{$session{'Attachments'}} and $ARGS{'id'} eq 'new') {
136 delete $session{'Attachments'};
139 my $checks_failure = 0;
141 my $gnupg_widget = $m->comp('/Elements/GnuPG/SignEncryptWidget:new', Arguments => \%ARGS );
142 $m->comp( '/Elements/GnuPG/SignEncryptWidget:Process',
143 self => $gnupg_widget,
144 QueueObj => $QueueObj,
148 if ( !exists $ARGS{'AddMoreAttach'} && ($ARGS{'id'}||'') eq 'new' ) {
149 my $status = $m->comp('/Elements/GnuPG/SignEncryptWidget:Check',
150 self => $gnupg_widget,
151 Operation => 'Create',
152 QueueObj => $QueueObj,
154 $checks_failure = 1 unless $status;
157 # check email addresses for RT's
159 foreach my $field ( qw(Requestors Cc AdminCc) ) {
160 my $value = $ARGS{ $field };
161 next unless defined $value && length $value;
163 my @emails = Email::Address->parse( $value );
164 foreach my $email ( grep RT::EmailParser->IsRTAddress($_->address), @emails ) {
165 push @results, loc("[_1] is an address RT receives mail at. Adding it as a '[_2]' would create a mail loop", $email->format, loc($field =~ /^(.*?)s?$/) );
169 $ARGS{ $field } = join ', ', map $_->format, grep defined, @emails;
174 $m->callback( CallbackName => 'BeforeCreate', ARGSRef => \%ARGS, skip_create => \$skip_create,
175 checks_failure => $checks_failure, results => \@results );
177 if ((!exists $ARGS{'AddMoreAttach'}) and (defined($ARGS{'id'}) and $ARGS{'id'} eq 'new')) { # new ticket?
178 if ( $ValidCFs && !$checks_failure && !$skip_create ) {
179 $m->comp('show', %ARGS);
180 $RT::Logger->crit("After display call; error is $@");
183 elsif ( !$ValidCFs ) {
185 while (my $CF = $CFs->Next) {
186 my $msg = $m->notes('InvalidField-' . $CF->Id) or next;
187 push @results, $CF->Name . ': ' . $msg;
196 <&| /m/_elements/wrapper, title => $title &>
197 <& /Elements/ListActions, actions => \@results &>
198 <form action="<% RT->Config->Get('WebPath') %>/m/ticket/create" method="post" enctype="multipart/form-data" name="TicketCreate" id="ticket-create">
199 <input type="hidden" class="hidden" name="id" value="new" />
200 % $m->callback( CallbackName => 'FormStart', QueueObj => $QueueObj, ARGSRef => \%ARGS );
201 % if ($gnupg_widget) {
202 <& /Elements/GnuPG/SignEncryptWidget:ShowIssues, self => $gnupg_widget &>
206 <div id="ticket-create-simple">
207 <&| /Widgets/TitleBox, title => $QueueObj->Name &>
211 loc("Subject") => '<input name="Subject" size="30" maxsize="200" value="'.$escape->($ARGS{Subject} || '').'" />');
213 <span class="content-label label"><%loc("Describe the issue below")%></span>
214 <& /Elements/MessageBox, exists $ARGS{Content} ? (Default => $ARGS{Content}, IncludeSignature => 0 ) : ( QuoteTransaction => $QuoteTransaction ), Height => 5 &>
217 <&/Elements/Submit, Label => loc("Create") &>
223 <div id="ticket-create-basics">
224 <&| /Widgets/TitleBox &>
225 <input type="hidden" class="hidden" name="Queue" value="<%$QueueObj->id %>" />
230 # loc('Queue') => $m->scomp( '/Ticket/Elements/ShowQueue', QueueObj => $QueueObj ) ,
235 "/Elements/SelectStatus",
237 Default => $ARGS{Status} || 'new',
245 "/Elements/SelectOwner",
247 QueueObj => $QueueObj,
248 Default => $ARGS{Owner} || $RT::Nobody->Id,
252 loc("Requestors") => $m->scomp(
253 "/Elements/EmailInput",
254 Name => 'Requestors',
256 Default => $ARGS{Requestors} || $session{CurrentUser}->EmailAddress
261 $m->scomp( "/Elements/EmailInput", Name => 'Cc', Size => '40', Default => $ARGS{Cc} )
262 . '<span class="comment"><i><font size="-2">'
264 "(Sends a carbon-copy of this update to a comma-delimited list of email addresses. These people <strong>will</strong> receive future updates.)"
266 . '</font></i></span>',
270 $m->scomp( "/Elements/EmailInput", Name => 'AdminCc', Size => '40', Default => $ARGS{AdminCc} )
271 . '<span class="comment" colspan="2"><i><font size="-2">'
273 "(Sends a carbon-copy of this update to a comma-delimited list of administrative email addresses. These people <strong>will</strong> receive future updates.)"
275 . '</font></i></span>',
281 $m->scomp("/Ticket/Elements/EditCustomFields", %ARGS, QueueObj => $QueueObj );
284 $m->scomp("/Ticket/Elements/EditTransactionCustomFields", %ARGS, QueueObj => $QueueObj );
287 % if (exists $session{'Attachments'}) {
289 <%loc("Attached file") %>
291 <%loc("Check box to delete")%><br />
292 % foreach my $attach_name (keys %{$session{'Attachments'}}) {
293 <input type="checkbox" class="checkbox" name="DeleteAttach-<%$attach_name%>" value="1" /><%$attach_name%><br />
301 loc("Attach file") =>
303 '<div class="value" colspan="5">
304 <input type="file" name="Attach" />
305 <input type="submit" class="button" name="AddMoreAttach" value="' . loc("Add More Files") . '" />'
310 % if ( $gnupg_widget ) {
311 %$m->scomp("/Elements/GnuPG/SignEncryptWidget", self => $gnupg_widget, QueueObj => $QueueObj )
315 <div class="ticket-info-basics">
316 <&| /Widgets/TitleBox, title => loc('The Basics'),
317 title_class=> 'inverse',
318 color => "#993333" &>
321 loc("Priority") => $m->scomp(
322 "/Elements/SelectPriority",
323 Name => "InitialPriority",
324 Default => $ARGS{InitialPriority} ? $ARGS{InitialPriority} : $QueueObj->InitialPriority,
326 loc("Final Priority") => $m->scomp(
327 "/Elements/SelectPriority",
328 Name => "FinalPriority",
329 Default => $ARGS{FinalPriority} ? $ARGS{FinalPriority} : $QueueObj->FinalPriority,
332 loc("Time Estimated") => '<span class="timefield">'.$m->scomp(
333 "/Elements/EditTimeValue",
334 Name => 'TimeEstimated',
335 Default => $ARGS{TimeEstimated} || '',
336 InUnits => $ARGS{'TimeEstimated-TimeUnits'}
339 loc("Time Worked") => '<span class="timefield">'.$m->scomp(
340 "/Elements/EditTimeValue",
341 Name => 'TimeWorked',
342 Default => $ARGS{TimeWorked} || '',
343 InUnits => $ARGS{'TimeWorked-TimeUnits'}
346 loc("Time Left") => '<span class="timefield">'.$m->scomp(
347 "/Elements/EditTimeValue",
349 Default => $ARGS{TimeLeft} || '',
350 InUnits => $ARGS{'TimeLeft-TimeUnits'}
356 <&|/Widgets/TitleBox, title => loc("Dates"),
357 title_class=> 'inverse',
358 color => "#663366" &>
362 loc("Starts") => $m->scomp( "/Elements/SelectDate", Name => "Starts", Default => ( $ARGS{Starts} || '' )),
363 loc("Due") => $m->scomp( "/Elements/SelectDate", Name => "Due", Default => ($ARGS{Due} || '' ))
369 <&|/Widgets/TitleBox, title => loc('Links'), title_class=> 'inverse' &>
371 <em><%loc("(Enter ticket ids or URLs, separated with spaces)")%></em>
375 loc("Depends on") => '<input type="text" size="10" name="new-DependsOn" value="' . $escape->($ARGS{'new-DependsOn'} || '' ). '" />',
376 loc("Depended on by") => '<input type="text" size="10" name="DependsOn-new" value="' . $escape->($ARGS{'DependsOn-new'} || '' ) . '" />',
377 loc("Parents") => '<input type="text" size="10" name="new-MemberOf" value="' . $escape->($ARGS{'new-MemberOf'} || '') . '" />',
378 loc("Children") => '<input type="text" size="10" name="MemberOf-new" value="' . $escape->($ARGS{'MemberOf-new'} || '') . '" />',
379 loc("Refers to") => '<input type="text" size="10" name="new-RefersTo" value="' . $escape->($ARGS{'new-RefersTo'} || '') . '" />',
380 loc("Referred to by") => '<input type="text" size="10" name="RefersTo-new" value="' . $escape->($ARGS{'RefersTo-new'} || ''). '" />'
387 <& /Elements/Submit, Label => loc("Create") &>