From 90edd8a914fd484e649fb0aa051dce7927bd6881 Mon Sep 17 00:00:00 2001 From: mark Date: Thu, 17 Feb 2011 03:47:50 +0000 Subject: TimeWorked-like custom fields, RT#11168 --- rt/lib/RT/Action/Accumulate.pm | 44 ++++++++++++++++++++++++++++++++++++++++ rt/lib/RT/Attribute_Overlay.pm | 9 +++----- rt/lib/RT/CustomField_Overlay.pm | 28 ++++++++++++++++++++++++- rt/lib/RT/Interface/Web.pm | 24 +++++++++++++++++----- rt/lib/RT/Record.pm | 2 ++ rt/lib/RT/Ticket_Overlay.pm | 5 ++++- rt/lib/RT/Transaction_Overlay.pm | 37 ++++++++++++++++++--------------- 7 files changed, 120 insertions(+), 29 deletions(-) create mode 100644 rt/lib/RT/Action/Accumulate.pm (limited to 'rt/lib/RT') diff --git a/rt/lib/RT/Action/Accumulate.pm b/rt/lib/RT/Action/Accumulate.pm new file mode 100644 index 000000000..c4ca667ea --- /dev/null +++ b/rt/lib/RT/Action/Accumulate.pm @@ -0,0 +1,44 @@ +package RT::Action::Accumulate; +use base 'RT::Action'; + +use strict; + +=head1 NAME + +RT::Action::Accumulate - Accumulate a running total in a ticket custom field. + +This action requires a transaction and ticket custom field with the same name. +When a transaction is submitted with a numeric value in that field, the field +value for the ticket will be incremented by that amount. Use this to create +custom fields that behave like the "TimeWorked" field. + +Best used with an "On Update" condition that triggers on any transaction. The +ticket custom field update itself does not a create a transaction. + +The argument to this action is the name of the custom field. They must have +the same name, and should be single-valued fields. + +=cut + +sub Prepare { + my $self = shift; + my $cfname = $self->Argument or return 0; + $self->{'inc_by'} = $self->TransactionObj->FirstCustomFieldValue($cfname); + return ( $self->{'inc_by'} =~ /^(\d+)$/ ); +} + +sub Commit { + my $self = shift; + my $cfname = $self->Argument; + my $newval = $self->{'inc_by'} + + ($self->TicketObj->FirstCustomFieldValue($cfname) || 0); + my ($val) = $self->TicketObj->AddCustomFieldValue( + Field => 'Support time', + Value => $newval, + RecordTransaction => 0, + ); + return $val; +} + +1; + diff --git a/rt/lib/RT/Attribute_Overlay.pm b/rt/lib/RT/Attribute_Overlay.pm index 58b5eb83a..1f69d46a8 100644 --- a/rt/lib/RT/Attribute_Overlay.pm +++ b/rt/lib/RT/Attribute_Overlay.pm @@ -309,12 +309,9 @@ Deletes the subvalue with the key NAME sub DeleteSubValue { my $self = shift; my $key = shift; - my %values = $self->Content(); - delete $values{$key}; - $self->SetContent(%values); - - - + my $values = $self->Content(); + delete $values->{$key}; + $self->SetContent($values); } diff --git a/rt/lib/RT/CustomField_Overlay.pm b/rt/lib/RT/CustomField_Overlay.pm index e2342e946..5e868d1c5 100644 --- a/rt/lib/RT/CustomField_Overlay.pm +++ b/rt/lib/RT/CustomField_Overlay.pm @@ -102,6 +102,11 @@ our %FieldTypes = ( 'Select date', # loc 'Select up to [_1] dates', # loc ], + TimeValue => [ + 'Enter multiple time values (UNSUPPORTED)', + 'Enter a time value', + 'Enter [_1] time values (UNSUPPORTED)', + ], ); @@ -261,6 +266,10 @@ sub Create { $self->SetBasedOn( $args{'BasedOn'} ); } + if ( exists $args{'UILocation'} ) { + $self->SetUILocation( $args{'UILocation'} ); + } + return ($rv, $msg) unless exists $args{'Queue'}; # Compat code -- create a new ObjectCustomField mapping @@ -835,7 +844,7 @@ Returns an array of all possible composite values for custom fields. sub TypeComposites { my $self = shift; - return grep !/(?:[Tt]ext|Combobox|Date)-0/, map { ("$_-1", "$_-0") } $self->Types; + return grep !/(?:[Tt]ext|Combobox|Date|TimeValue)-0/, map { ("$_-1", "$_-0") } $self->Types; } =head2 SetLookupType @@ -1447,4 +1456,21 @@ sub BasedOnObj { return $obj; } +sub UILocation { + my $self = shift; + my $tag = $self->FirstAttribute( 'UILocation' ); + return $tag ? $tag->Content : ''; +} + +sub SetUILocation { + my $self = shift; + my $tag = shift; + if ( $tag ) { + return $self->SetAttribute( Name => 'UILocation', Content => $tag ); + } + else { + return $self->DeleteAttribute('UILocation'); + } +} + 1; diff --git a/rt/lib/RT/Interface/Web.pm b/rt/lib/RT/Interface/Web.pm index 2990f3ea3..4e4611bdb 100644 --- a/rt/lib/RT/Interface/Web.pm +++ b/rt/lib/RT/Interface/Web.pm @@ -1334,13 +1334,22 @@ sub ProcessUpdateMessage { my $bcc = $args{ARGSRef}->{'UpdateBcc'}; my $cc = $args{ARGSRef}->{'UpdateCc'}; + my %txn_customfields; + + foreach my $key ( keys %{ $args{ARGSRef} } ) { + if ( $key =~ /^(?:Object-RT::Transaction--)?CustomField-(\d+)/ ) { + $txn_customfields{$key} = $args{ARGSRef}->{$key}; + } + } + my %message_args = ( CcMessageTo => $cc, BccMessageTo => $bcc, Sign => $args{ARGSRef}->{'Sign'}, Encrypt => $args{ARGSRef}->{'Encrypt'}, MIMEObj => $Message, - TimeTaken => $args{ARGSRef}->{'UpdateTimeWorked'} + TimeTaken => $args{ARGSRef}->{'UpdateTimeWorked'}, + CustomFields => \%txn_customfields, ); my @temp_squelch; @@ -1376,14 +1385,17 @@ sub ProcessUpdateMessage { } 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); + my ( $Transaction, $Description, $Object ) = + $args{TicketObj}->Comment(%message_args); push( @results, $Description ); - $Object->UpdateCustomFields( ARGSRef => $args{ARGSRef} ) if $Object; + #$Object->UpdateCustomFields( ARGSRef => $args{ARGSRef} ) if $Object; } elsif ( $args{ARGSRef}->{'UpdateType'} eq 'response' ) { - my ( $Transaction, $Description, $Object ) = $args{TicketObj}->Correspond(%message_args); + my ( $Transaction, $Description, $Object ) = + $args{TicketObj}->Correspond(%message_args); push( @results, $Description ); - $Object->UpdateCustomFields( ARGSRef => $args{ARGSRef} ) if $Object; + #$Object->UpdateCustomFields( ARGSRef => $args{ARGSRef} ) if $Object; } else { push( @results, loc("Update type was neither correspondence nor comment.") . " " . loc("Update not recorded.") ); @@ -1716,6 +1728,8 @@ sub ProcessTicketCustomFieldUpdates { $ARGSRef->{"Object-RT::Ticket-$1"} = delete $ARGSRef->{$arg}; } elsif ( $arg =~ /^CustomField-(\d+-.*)/ ) { $ARGSRef->{"Object-RT::Ticket--$1"} = delete $ARGSRef->{$arg}; + } elsif ( $arg =~ /^Object-RT::Transaction-(\d*)-CustomField/ ) { + delete $ARGSRef->{$arg}; # don't try to update transaction fields } } diff --git a/rt/lib/RT/Record.pm b/rt/lib/RT/Record.pm index c87626a21..ce46a90a6 100755 --- a/rt/lib/RT/Record.pm +++ b/rt/lib/RT/Record.pm @@ -1467,6 +1467,7 @@ sub _NewTransaction { MIMEObj => undef, ActivateScrips => 1, CommitScrips => 1, + CustomFields => {}, @_ ); @@ -1500,6 +1501,7 @@ sub _NewTransaction { MIMEObj => $args{'MIMEObj'}, ActivateScrips => $args{'ActivateScrips'}, CommitScrips => $args{'CommitScrips'}, + CustomFields => $args{'CustomFields'}, ); # Rationalize the object since we may have done things to it during the caching. diff --git a/rt/lib/RT/Ticket_Overlay.pm b/rt/lib/RT/Ticket_Overlay.pm index e4db79a91..e1809a377 100644 --- a/rt/lib/RT/Ticket_Overlay.pm +++ b/rt/lib/RT/Ticket_Overlay.pm @@ -734,7 +734,8 @@ sub Create { if ( $self->Id && $Trans ) { - $TransObj->UpdateCustomFields(ARGSRef => \%args); + #$TransObj->UpdateCustomFields(ARGSRef => \%args); + $TransObj->UpdateCustomFields(%args); $RT::Logger->info( "Ticket " . $self->Id . " created in queue '" . $QueueObj->Name . "' by " . $self->CurrentUser->Name ); $ErrStr = $self->loc( "Ticket [_1] created in queue '[_2]'", $self->Id, $QueueObj->Name ); @@ -2222,6 +2223,7 @@ sub _RecordNote { NoteType => 'Correspond', TimeTaken => 0, CommitScrips => 1, + CustomFields => {}, @_ ); @@ -2278,6 +2280,7 @@ sub _RecordNote { TimeTaken => $args{'TimeTaken'}, MIMEObj => $args{'MIMEObj'}, CommitScrips => $args{'CommitScrips'}, + CustomFields => $args{'CustomFields'}, ); unless ($Trans) { diff --git a/rt/lib/RT/Transaction_Overlay.pm b/rt/lib/RT/Transaction_Overlay.pm index c9e13dd77..d4b1ab2bc 100644 --- a/rt/lib/RT/Transaction_Overlay.pm +++ b/rt/lib/RT/Transaction_Overlay.pm @@ -110,12 +110,13 @@ sub Create { NewValue => undef, MIMEObj => undef, ActivateScrips => 1, - CommitScrips => 1, - ObjectType => 'RT::Ticket', - ObjectId => 0, - ReferenceType => undef, - OldReference => undef, - NewReference => undef, + CommitScrips => 1, + ObjectType => 'RT::Ticket', + ObjectId => 0, + ReferenceType => undef, + OldReference => undef, + NewReference => undef, + CustomFields => {}, @_ ); @@ -130,17 +131,17 @@ sub Create { #lets create our transaction my %params = ( - Type => $args{'Type'}, - Data => $args{'Data'}, - Field => $args{'Field'}, - OldValue => $args{'OldValue'}, - NewValue => $args{'NewValue'}, - Created => $args{'Created'}, - ObjectType => $args{'ObjectType'}, - ObjectId => $args{'ObjectId'}, + Type => $args{'Type'}, + Data => $args{'Data'}, + Field => $args{'Field'}, + OldValue => $args{'OldValue'}, + NewValue => $args{'NewValue'}, + Created => $args{'Created'}, + ObjectType => $args{'ObjectType'}, + ObjectId => $args{'ObjectId'}, ReferenceType => $args{'ReferenceType'}, - OldReference => $args{'OldReference'}, - NewReference => $args{'NewReference'}, + OldReference => $args{'OldReference'}, + NewReference => $args{'NewReference'}, ); # Parameters passed in during an import that we probably don't want to touch, otherwise @@ -158,6 +159,10 @@ sub Create { } } + # Set up any custom fields passed at creation. Has to happen + # before scrips. + + $self->UpdateCustomFields(%{ $args{'CustomFields'} }); #Provide a way to turn off scrips if we need to $RT::Logger->debug('About to think about scrips for transaction #' .$self->Id); -- cgit v1.2.1