How to detect a custom field change in a scrip

Hiya, we use custom fields and they work well so far.

Now I’d like to do something in a scrip if the content of
one of my custom fields changes, say, from “foo” to “bar”.
I know how to check if the field is “bar”, but I don’t know
how to find out if it always has been “bar” before, or if
the user just changed it from “foo”.

Is there a way to run a scrip on the condition “value of a
certain custom field changed”, or should I rather let the
scrip run “On Transaction” and check the current field value
against its previous value? How to do it?

Ciao, Lobo

Lobo,

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.

Kenn
LBNLOn Thu, Apr 29, 2010 at 6:58 AM, <lobo+rt@mental.com lobo%2Brt@mental.com>wrote:

Hiya, we use custom fields and they work well so far.

Now I’d like to do something in a scrip if the content of
one of my custom fields changes, say, from “foo” to “bar”.
I know how to check if the field is “bar”, but I don’t know
how to find out if it always has been “bar” before, or if
the user just changed it from “foo”.

Is there a way to run a scrip on the condition “value of a
certain custom field changed”, or should I rather let the
scrip run “On Transaction” and check the current field value
against its previous value? How to do it?

Ciao, Lobo

Discover RT’s hidden secrets with RT Essentials from O’Reilly Media.
Buy a copy at http://rtbook.bestpractical.com

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

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

Process");

 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
change.

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,

RecordTransaction=>0);

}

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

reformatting)

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 );

$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);

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 );

$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);

set new value for CF “QA Approver” (use the name of the user doing this

trans)

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
code

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

$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.

Kenn

LBNLOn Thu, Apr 29, 2010 at 9:52 AM, <lobo+rt@mental.com lobo%2Brt@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