From 53c18558abf77ea27c56dc51c5ca40a80e0d35ab Mon Sep 17 00:00:00 2001 From: mark Date: Mon, 24 Oct 2011 22:50:47 +0000 Subject: [PATCH] record support time even without comment text, #14837 --- httemplate/search/rt_ticket.html | 2 +- httemplate/search/rt_transaction.html | 8 +- rt/lib/RT/Interface/Web_Vendor.pm | 173 ++++++++++++++++++++++++++++++++++ rt/lib/RT/Ticket_Vendor.pm | 31 ++++++ rt/lib/RT/Transaction_Vendor.pm | 2 + 5 files changed, 211 insertions(+), 5 deletions(-) diff --git a/httemplate/search/rt_ticket.html b/httemplate/search/rt_ticket.html index 7ffe55fc1..abe13157d 100644 --- a/httemplate/search/rt_ticket.html +++ b/httemplate/search/rt_ticket.html @@ -67,7 +67,7 @@ my $twhere = " AND ( ( Transactions.Type = 'Set' AND Transactions.Field = 'TimeWorked' AND Transactions.NewValue != Transactions.OldValue ) - OR ( ( Transactions.Type='Create' OR Transactions.Type='Comment' OR Transactions.Type='Correspond' ) + OR ( ( Transactions.Type='Create' OR Transactions.Type='Comment' OR Transactions.Type='Correspond' OR Transactions.Type='Touch' ) AND Transactions.TimeTaken > 0 ) ) diff --git a/httemplate/search/rt_transaction.html b/httemplate/search/rt_transaction.html index ab5636347..be9cd0bc9 100644 --- a/httemplate/search/rt_transaction.html +++ b/httemplate/search/rt_transaction.html @@ -47,9 +47,9 @@ die "access denied" #some amount of false laziness w/timeworked.html... my $transactiontime = " - CASE transactions.type when 'Set' - THEN (to_number(newvalue,'999999')-to_number(oldvalue, '999999')) * 60 - ELSE timetaken*60 + CASE Transactions.Type when 'Set' + THEN (to_number(NewValue,'999999')-to_number(OldValue, '999999')) * 60 + ELSE TimeTaken*60 END "; @@ -62,7 +62,7 @@ my $where = " AND ( ( Transactions.Type = 'Set' AND Transactions.Field = 'TimeWorked' AND Transactions.NewValue != Transactions.OldValue ) - OR ( ( Transactions.Type='Create' OR Transactions.Type='Comment' OR Transactions.Type='Correspond' ) + OR ( ( Transactions.Type='Create' OR Transactions.Type='Comment' OR Transactions.Type='Correspond' OR Transactions.Type='Touch' ) AND Transactions.TimeTaken > 0 ) ) diff --git a/rt/lib/RT/Interface/Web_Vendor.pm b/rt/lib/RT/Interface/Web_Vendor.pm index 27c647f18..129f69fab 100644 --- a/rt/lib/RT/Interface/Web_Vendor.pm +++ b/rt/lib/RT/Interface/Web_Vendor.pm @@ -352,5 +352,178 @@ sub ProcessTicketStatus { ); } +=head2 ProcessUpdateMessage + +Takes paramhash with fields ARGSRef, TicketObj and SkipSignatureOnly. + +Don't write message if it only contains current user's signature and +SkipSignatureOnly argument is true. Function anyway adds attachments +and updates time worked field even if skips message. The default value +is true. + +=cut + +# change from stock: if txn custom fields are set but there's no content +# or attachment, create a Touch txn instead of doing nothing + +sub ProcessUpdateMessage { + + my %args = ( + ARGSRef => undef, + TicketObj => undef, + SkipSignatureOnly => 1, + @_ + ); + + if ( $args{ARGSRef}->{'UpdateAttachments'} + && !keys %{ $args{ARGSRef}->{'UpdateAttachments'} } ) + { + delete $args{ARGSRef}->{'UpdateAttachments'}; + } + + # Strip the signature + $args{ARGSRef}->{UpdateContent} = RT::Interface::Web::StripContent( + Content => $args{ARGSRef}->{UpdateContent}, + ContentType => $args{ARGSRef}->{UpdateContentType}, + StripSignature => $args{SkipSignatureOnly}, + CurrentUser => $args{'TicketObj'}->CurrentUser, + ); + + my %txn_customfields; + + foreach my $key ( keys %{ $args{ARGSRef} } ) { + if ( $key =~ /^(?:Object-RT::Transaction--)?CustomField-(\d+)/ ) { + next if $key =~ /(TimeUnits|Magic)$/; + $txn_customfields{$key} = $args{ARGSRef}->{$key}; + } + } + + # If, after stripping the signature, we have no message, create a + # Touch transaction if necessary + if ( not $args{ARGSRef}->{'UpdateAttachments'} + and not length $args{ARGSRef}->{'UpdateContent'} ) + { + #if ( $args{ARGSRef}->{'UpdateTimeWorked'} ) { + # $args{ARGSRef}->{TimeWorked} = $args{TicketObj}->TimeWorked + + # delete $args{ARGSRef}->{'UpdateTimeWorked'}; + # } + + my $timetaken = $args{ARGSRef}->{'UpdateTimeWorked'}; + if ( $timetaken or grep {length $_} values %txn_customfields ) { + my ( $Transaction, $Description, $Object ) = + $args{TicketObj}->Touch( + CustomFields => \%txn_customfields, + TimeTaken => $timetaken + ); + return $Description; + } + + return; + } + + if ( $args{ARGSRef}->{'UpdateSubject'} eq $args{'TicketObj'}->Subject ) { + $args{ARGSRef}->{'UpdateSubject'} = undef; + } + + my $Message = MakeMIMEEntity( + Subject => $args{ARGSRef}->{'UpdateSubject'}, + Body => $args{ARGSRef}->{'UpdateContent'}, + Type => $args{ARGSRef}->{'UpdateContentType'}, + ); + + $Message->head->add( 'Message-ID' => Encode::encode_utf8( + RT::Interface::Email::GenMessageId( Ticket => $args{'TicketObj'} ) + ) ); + my $old_txn = RT::Transaction->new( $session{'CurrentUser'} ); + if ( $args{ARGSRef}->{'QuoteTransaction'} ) { + $old_txn->Load( $args{ARGSRef}->{'QuoteTransaction'} ); + } else { + $old_txn = $args{TicketObj}->Transactions->First(); + } + + if ( my $msg = $old_txn->Message->First ) { + RT::Interface::Email::SetInReplyTo( + Message => $Message, + InReplyTo => $msg + ); + } + + if ( $args{ARGSRef}->{'UpdateAttachments'} ) { + $Message->make_multipart; + $Message->add_part($_) foreach values %{ $args{ARGSRef}->{'UpdateAttachments'} }; + } + + if ( $args{ARGSRef}->{'AttachTickets'} ) { + require RT::Action::SendEmail; + RT::Action::SendEmail->AttachTickets( RT::Action::SendEmail->AttachTickets, + ref $args{ARGSRef}->{'AttachTickets'} + ? @{ $args{ARGSRef}->{'AttachTickets'} } + : ( $args{ARGSRef}->{'AttachTickets'} ) ); + } + + my $bcc = $args{ARGSRef}->{'UpdateBcc'}; + my $cc = $args{ARGSRef}->{'UpdateCc'}; + + my %message_args = ( + CcMessageTo => $cc, + BccMessageTo => $bcc, + Sign => $args{ARGSRef}->{'Sign'}, + Encrypt => $args{ARGSRef}->{'Encrypt'}, + MIMEObj => $Message, + TimeTaken => $args{ARGSRef}->{'UpdateTimeWorked'}, + CustomFields => \%txn_customfields, + ); + + my @temp_squelch; + foreach my $type (qw(Cc AdminCc)) { + if (grep $_ eq $type || $_ eq ( $type . 's' ), @{ $args{ARGSRef}->{'SkipNotification'} || [] }) { + push @temp_squelch, map $_->address, Email::Address->parse( $message_args{$type} ); + push @temp_squelch, $args{TicketObj}->$type->MemberEmailAddresses; + push @temp_squelch, $args{TicketObj}->QueueObj->$type->MemberEmailAddresses; + } + } + if (grep $_ eq 'Requestor' || $_ eq 'Requestors', @{ $args{ARGSRef}->{'SkipNotification'} || [] }) { + push @temp_squelch, map $_->address, Email::Address->parse( $message_args{Requestor} ); + push @temp_squelch, $args{TicketObj}->Requestors->MemberEmailAddresses; + } + + if (@temp_squelch) { + require RT::Action::SendEmail; + RT::Action::SendEmail->SquelchMailTo( RT::Action::SendEmail->SquelchMailTo, @temp_squelch ); + } + + unless ( $args{'ARGSRef'}->{'UpdateIgnoreAddressCheckboxes'} ) { + foreach my $key ( keys %{ $args{ARGSRef} } ) { + next unless $key =~ /^Update(Cc|Bcc)-(.*)$/; + + my $var = ucfirst($1) . 'MessageTo'; + my $value = $2; + if ( $message_args{$var} ) { + $message_args{$var} .= ", $value"; + } else { + $message_args{$var} = $value; + } + } + } + + my @results; + # Do the update via the appropriate Ticket method + if ( $args{ARGSRef}->{'UpdateType'} =~ /^(private|public)$/ ) { + my ( $Transaction, $Description, $Object ) = + $args{TicketObj}->Comment(%message_args); + push( @results, $Description ); + #$Object->UpdateCustomFields( ARGSRef => $args{ARGSRef} ) if $Object; + } elsif ( $args{ARGSRef}->{'UpdateType'} eq 'response' ) { + my ( $Transaction, $Description, $Object ) = + $args{TicketObj}->Correspond(%message_args); + push( @results, $Description ); + #$Object->UpdateCustomFields( ARGSRef => $args{ARGSRef} ) if $Object; + } else { + push( @results, + loc("Update type was neither correspondence nor comment.") . " " . loc("Update not recorded.") ); + } + return @results; +} + 1; diff --git a/rt/lib/RT/Ticket_Vendor.pm b/rt/lib/RT/Ticket_Vendor.pm index 9fa24a2a8..a55bb7b0d 100644 --- a/rt/lib/RT/Ticket_Vendor.pm +++ b/rt/lib/RT/Ticket_Vendor.pm @@ -13,6 +13,37 @@ sub SetPriority { $Ticket->SUPER::SetPriority($value); } +=head2 Touch + +Creates a Touch transaction (a null transaction). Like Comment and +Correspond but without any content. + +=cut + +sub Touch { + my $self = shift; + my %args = ( + TimeTaken => 0, + ActivateScrips => 1, + CommitScrips => 1, + CustomFields => {}, + @_ + ); + unless ( $self->CurrentUserHasRight('ModifyTicket') + or $self->CurrentUserHasRight('CommentOnTicket') + or $self->CurrentUserHasRight('ReplyToTicket')) { + return ( 0, $self->loc("Permission Denied")); + } + $self->_NewTransaction( + Type => 'Touch', + TimeTaken => $args{'TimeTaken'}, + ActivateScrips => $args{'ActivateScrips'}, + CommitScrips => $args{'CommitScrips'}, + CustomFields => $args{'CustomFields'}, + ); +} + + =head2 MissingRequiredFields { Return all custom fields with the Required flag set for which this object diff --git a/rt/lib/RT/Transaction_Vendor.pm b/rt/lib/RT/Transaction_Vendor.pm index caeb3f72c..99198c2f0 100644 --- a/rt/lib/RT/Transaction_Vendor.pm +++ b/rt/lib/RT/Transaction_Vendor.pm @@ -31,5 +31,7 @@ $_BriefDescriptions{'Set'} = sub { } }; +$_BriefDescriptions{'Touch'} = sub { 'Updated' }; + 1; -- 2.11.0