[rt-users] How to detect a custom field change in a scrip

Kenneth Crocker kfcrocker at lbl.gov
Thu Apr 29 13:10:15 EDT 2010

OK, I've got some examples for you.

First, let's talk about conditions. If your condition is simple, like just a
status change, then that's all you need. But the moment you want to combine
a status change with some other info, like a CF value, then you need to
specify "User-Defined" for the condition.

Below is an example of a condition that checks the value of a CF (this is
triggered *ONLY* when this particular CF is changed on a ticket):

# Custom Condition
# Check for CF "Review Process" with value of "Review Complete-Approved"

my $trans = $self->TransactionObj;
my $ticket = $self->TicketObj;

if  ($trans->Type eq 'CustomField')

    {my $cf = new RT::CustomField($RT::SystemUser);

     $cf->LoadByName(Queue => $ticket->QueueObj->id,Name => "Review

     return 0 unless $cf->id;

     if  ($trans->Field == $cf->id &&

          $trans->NewValue eq "Review Complete-Approved")


           return 1;



return 0;

Here you'll notice that if this transaction is for some other Custom Field,
it drops out (return 0:) *and then checks* for the right value of the

You can apply this type of code for any Custom Field. If you need to also
check the Ticket Status, you can add that. I'd add(check) it up front. No
sense checking data when the ticket isn't the right status. You can also
check the Queue, like we discussed before.

Now we'll go over Custom Actions. There are two types; "Preparation &
Cleanup. Where to put what?

My line of thinking is to use Preparation in almost all cases. Reason, I may
have other scrips that I want triggered by values I modify. For example, if
my code is changing the Ticket Status to "resolved", I want to do that in
the "Prep" area because that WAY RT will be aware of it BEFORE it ends the
transaction and can trigger another scrip that modifies some other Custom
Field value. The more I do before RT starts cleaning up, the more modified
data is available for RT for any cleanup work, etc.

Also, in order to ensure that any changes to Custom Fields remain, you want
to set your RT_SiteConfig.pm settings to turn on the "TransactionBatch"
option *Set($UseTransactionBatch, '1');*.

So, the next piece of code will be Custom Preparation code:


# Custom action preparation code:

# Set the value for the Custom Field "Work-State"

my $trans = $self->TransactionObj;

my $ticket = $self->TicketObj;

my $cf_obj = RT::CustomField->new($RT::SystemUser);

my $cf_name = "Work-State";

my $cf_value = "Acceptance Testing";

my $current = $ticket->FirstCustomFieldValue('Work-State');

# Won't change if current value is whatever

if  ($current ne "In Production - Not Yet Used" &&

     $current ne "In Production - Verification Required" &&

     $current ne "Installing Modifications")


     $cf_obj->LoadByName( Name => $cf_name );

     $RT::Logger->debug("Loaded \$cf_obj->Name = ". $cf_obj->Name() ."\n");

     $ticket->AddCustomFieldValue( Field=>$cf_obj, Value=>$cf_value,


# set the CF Work-Completed Date (date is in mm/dd/yyyy format and needs

my $cf_name = "Work-Completed Date";

my ( undef, undef, undef, $day, $mon, $year ) = localtime( time );

my $cf_value = sprintf( '%d/%02d/%02d', $year + 1900, $mon + 1, $day );


$RT::Logger->debug("Loaded\$cf_obj->Name = ". $cf_obj->Name() ."\n");

$ticket->AddCustomFieldValue(Field=>$cf_obj, Value=>$cf_value,

# set the CF "QA Approval Date" (use the current system date)

my $cf_name = "QA Approval Date";
my ( undef, undef, undef, $day, $mon, $year ) = localtime( time );
my $cf_value = sprintf( '%d/%02d/%02d', $year + 1900, $mon + 1, $day );

$RT::Logger->debug("Loaded\$cf_obj->Name = ". $cf_obj->Name() ."\n");
$ticket->AddCustomFieldValue(Field=>$cf_obj, Value=>$cf_value,

# set new value for CF "QA Approver" (use the name of the user doing this

my $cf_name = "QA Approver";
my $cf_value = $trans->CreatorObj->Name;
my $approver = $ticket->FirstCustomFieldValue('QA Approver');

# Before continuing, check to see if QA Approver is blank

unless ($approver)
        $cf_obj->LoadByName( Name => $cf_name );
        $RT::Logger->debug( "Loaded \$cf_obj->Name = ". $cf_obj->Name()
."\n" );
        $ticket->AddCustomFieldValue( Field=>$cf_obj, Value=>$cf_value,
RecordTransaction=>0 );

return 1;


# Custom action cleanup code:


 return 1;

As you can see, there's a lot of code you can use there for Custom Fields,
compound if's, etc.

Now, here are a couple pieces of code to modify certain Ticket fields:

$ticket->SetOwner($ownerid); # $ownerid was set previously to this line of

$ticket->SetQueue(10, 'Force'); # 10 is the ID of the Queue I want it moved

$ticket->SetOwner(10, 'Force'); # Forces *change* in owner (in this case to
ID #10) as opposed to simply setting an empty field

Notice that in some cases, you might have to use "Force". Most likely, you
will have to do that to "move" a ticket to *another* Queue. Actually, you
aren't really "*moving*" anything. You're just changing the Queue ID for
that ticket. To do this, you need that *actual Queue Id* to set it to. You
can get the ID by navigating Configuration->Queues and the number on the
left is the Queue Id.

Here's code that will set the owner to the transaction user if there is no
current owner:

# set owner if Nobody

my $ticket = $self->TicketObj;
my $trans = $self->TransactionObj;
my $owner_id = $trans->CreatorObj->PrincipalId;

if  ($ticket->OwnerObj->Name() eq 'Nobody' )
     $ticket->SetOwner($owner_id, 'Force');

return 1;

Well, that's about it. Hope this all helps.



On Thu, Apr 29, 2010 at 9:52 AM, <lobo+rt at mental.com
<lobo%2Brt at mental.com>>wrote:

> Kenn,
> () Do you REALLY care what the old value was? We use Custom Fields as
> triggers
> () on a lot of scrips, but we really don't care what it used to be. We only
> () care that it has changed and what it has changed to. It makes the code
> () easier to write and debug.
> yes, I only care about the new value and that it actually has
> changed, sorry for not being more clear.
> Your mail made me search for "trigger", and that lead me to
> http://wiki.bestpractical.com/view/OnCustomFieldValueChange
> which looks as if tells me all I need.  Thank you very much!
>    Ciao, Lobo
> Discover RT's hidden secrets with RT Essentials from O'Reilly Media.
> Buy a copy at http://rtbook.bestpractical.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.bestpractical.com/pipermail/rt-users/attachments/20100429/e0423068/attachment.htm>

More information about the rt-users mailing list