Difference between revisions of "CustomConditionSnippets"

From Request Tracker Wiki
Jump to navigation Jump to search
(Fixing greater than and adding pre blocks)
 
Line 13: Line 13:
== On Create and variants ==
== On Create and variants ==


  return 0 unless $self->TransactionObj->Type eq "Create";
<pre>
  return 1;
return 0 unless $self->TransactionObj->Type eq "Create";
return 1;
</pre>


=== On Create, but queue is not 'xxx' ===
=== On Create, but queue is not 'xxx' ===


  <nowiki>
<pre>
    return 0 unless $self->TransactionObj->Type eq "Create";
return 0 unless $self->TransactionObj->Type eq "Create";
    return 0 if $self-&gt;TicketObj-&gt;QueueObj-&gt;Name eq "xxx";
return 0 if $self->TicketObj->QueueObj->Name eq "xxx";
    return 1;
return 1;
    </nowiki>
</pre>


=== On Create with status resolved ===
=== On Create with status resolved ===
Line 28: Line 30:
If you create [[Ticket]] with status resolved then standard RT condition OnResolve wouldn't trigger.
If you create [[Ticket]] with status resolved then standard RT condition OnResolve wouldn't trigger.


return 0 unless $self-&gt;TransactionObj-&gt;Type eq "Create";
<pre>
return 0 unless $self-&gt;TicketObj-&gt;Status eq 'resolved';
return 0 unless $self->TransactionObj->Type eq "Create";
return 1;
return 0 unless $self->TicketObj->Status eq 'resolved';
return 1;
</pre>


== On Correspond/Comment and variants ==
== On Correspond/Comment and variants ==


  return 0 unless $self-&gt;TransactionObj-&gt;Type eq "Correspond";
<pre>
  return 1;
return 0 unless $self->TransactionObj->Type eq "Correspond";
return 1;
</pre>


=== On Correspond to Unowned Ticket ===
=== On Correspond to Unowned Ticket ===


  return 0 unless $self-&gt;TransactionObj-&gt;Type eq "Correspond";
<pre>
  return 0 unless $self-&gt;TicketObj-&gt;Owner == $RT::Nobody-&gt;id;
return 0 unless $self->TransactionObj->Type eq "Correspond";
  return 1;
return 0 unless $self->TicketObj->Owner == $RT::Nobody->id;
return 1;
</pre>


Can be used in "On Correspond to Unowned Notify Admin Ccs With Admin Correspondence".
Can be used in "On Correspond to Unowned Notify Admin Ccs With Admin Correspondence".
Line 49: Line 57:
For historical reasons it's more correct to write this condition like this:
For historical reasons it's more correct to write this condition like this:


my $txn = $self-&gt;TransactionObj;
<pre>
my $type = $txn-&gt;Type;
my $txn = $self->TransactionObj;
return 0 unless $type eq "Status"
my $type = $txn->Type;
    || ( $type eq 'Set' && $txn->Field eq 'Status');
return 0 unless $type eq "Status"
return 1;
    || ( $type eq 'Set' && $txn->Field eq 'Status');
return 1;
</pre>


=== On Status Change to "resolved" ===
=== On Status Change to "resolved" ===
<pre>
<pre>
my $txn = $self-&gt;TransactionObj;
my $txn = $self->TransactionObj;
my $type = $txn-&gt;Type;
my $type = $txn->Type;
return 0 unless $type eq "Status"
return 0 unless $type eq "Status"
    || ( $type eq 'Set' && $txn->Field eq 'Status');
    || ( $type eq 'Set' && $txn->Field eq 'Status');


return 0 unless $txn-&gt;NewValue eq "resolved";
return 0 unless $txn->NewValue eq "resolved";
return 1;
return 1;
</pre>
</pre>


=== on Status Change from "new" to "open" ===
=== on Status Change from "new" to "open" ===


my $txn = $self-&gt;TransactionObj;
<pre>
my $type = $txn-&gt;Type;
my $txn = $self->TransactionObj;
return 0 unless $type eq "Status"
my $type = $txn->Type;
    || ( $type eq 'Set' && $txn->Field eq 'Status');
return 0 unless $type eq "Status"
    || ( $type eq 'Set' && $txn->Field eq 'Status');


return 0 unless $txn-&gt;OldValue eq "new";
return 0 unless $txn->OldValue eq "new";
return 0 unless $txn-&gt;NewValue eq "open";
return 0 unless $txn->NewValue eq "open";
return 1;
return 1;
</pre>


== On Queue Change ==
== On Queue Change ==
 
<pre>
return 0 unless $self-&gt;TransactionObj-&gt;Type eq "Set";
return 0 unless $self->TransactionObj->Type eq "Set";
return 0 unless $self-&gt;TransactionObj-&gt;Field eq "Queue";
return 0 unless $self->TransactionObj->Field eq "Queue";
return 1;
return 1;
 
</pre>
== On Owner Change and variants ==
== On Owner Change and variants ==
 
<pre>
return 0 unless $self-&gt;TransactionObj-&gt;Type eq "Set";
return 0 unless $self->TransactionObj->Type eq "Set";
return 0 unless $self-&gt;TransactionObj-&gt;Field eq "Owner";
return 0 unless $self->TransactionObj->Field eq "Owner";
return 1;
return 1;
</pre>


=== On Owner Change from Nobody to Any ===
=== On Owner Change from Nobody to Any ===
 
<pre>
my $txn = $self-&gt;TransactionObj;
my $txn = $self->TransactionObj;
return 0 unless $txn-&gt;Type eq "Set";
return 0 unless $txn->Type eq "Set";
return 0 unless $txn-&gt;Field eq "Owner";
return 0 unless $txn->Field eq "Owner";
return 0 unless $txn-&gt;OldValue == $RT::Nobody-&gt;id;
return 0 unless $txn->OldValue == $RT::Nobody->id;
return 1;
return 1;
</pre>


=== On Take ===
=== On Take ===
 
<pre>
my $txn = $self-&gt;TransactionObj;
my $txn = $self->TransactionObj;
return 0 unless $txn-&gt;Type eq "Set";
return 0 unless $txn->Type eq "Set";
return 0 unless $txn-&gt;Field eq "Owner";
return 0 unless $txn->Field eq "Owner";
return 0 unless $txn-&gt;OldValue == $RT::Nobody-&gt;id;
return 0 unless $txn->OldValue == $RT::Nobody->id;
return 0 unless $txn-&gt;NewValue == $txn-&gt;Creator;
return 0 unless $txn->NewValue == $txn->Creator;
return 1;
return 1;
</pre>


=== On Steal ===
=== On Steal ===


See also [[OnStealEnhanced]]
See also [[OnStealEnhanced]]
 
<pre>
my $txn = $self-&gt;TransactionObj;
my $txn = $self->TransactionObj;
return 0 unless $txn-&gt;Type eq "Set";
return 0 unless $txn->Type eq "Set";
return 0 unless $txn-&gt;Field eq "Owner";
return 0 unless $txn->Field eq "Owner";
return 0 if $txn-&gt;OldValue == $RT::Nobody-&gt;id;
return 0 if $txn->OldValue == $RT::Nobody->id;
return 0 unless $txn-&gt;NewValue == $txn-&gt;Creator;
return 0 unless $txn->NewValue == $txn->Creator;
return 1;
return 1;
</pre>


=== On Give ===
=== On Give ===
 
<pre>
my $txn = $self-&gt;TransactionObj;
my $txn = $self->TransactionObj;
return 0 unless $txn-&gt;Type eq "Set";
return 0 unless $txn->Type eq "Set";
return 0 unless $txn-&gt;Field eq "Owner";
return 0 unless $txn->Field eq "Owner";
return 0 unless $txn-&gt;OldValue == $RT::Nobody-&gt;id;
return 0 unless $txn->OldValue == $RT::Nobody->id;
return 0 if $txn-&gt;NewValue == $txn-&gt;Creator;
return 0 if $txn->NewValue == $txn->Creator;
return 1;
return 1;
</pre>


=== On Give Up ===
=== On Give Up ===
 
<pre>
my $txn = $self-&gt;TransactionObj;
my $txn = $self->TransactionObj;
return 0 unless $txn-&gt;Type eq "Set";
return 0 unless $txn->Type eq "Set";
return 0 unless $txn-&gt;Field eq "Owner";
return 0 unless $txn->Field eq "Owner";
return 0 unless $txn-&gt;OldValue == $txn-&gt;Creator;
return 0 unless $txn->OldValue == $txn->Creator;
return 0 unless $txn-&gt;NewValue == $RT::Nobody-&gt;id;
return 0 unless $txn->NewValue == $RT::Nobody->id;
return 1;
return 1;
</pre>


=== On Assign ===
=== On Assign ===
 
<pre>
my $txn = $self-&gt;TransactionObj;
my $txn = $self->TransactionObj;
return 0 unless $txn-&gt;Type eq "Set";
return 0 unless $txn->Type eq "Set";
return 0 unless $txn-&gt;Field eq "Owner";
return 0 unless $txn->Field eq "Owner";
return 0 unless $txn-&gt;OldValue == $RT::Nobody-&gt;id;
return 0 unless $txn->OldValue == $RT::Nobody->id;
return 0 if $txn-&gt;NewValue == $txn-&gt;Creator;
return 0 if $txn->NewValue == $txn->Creator;
return 1;
return 1;
</pre>


=== On Re-Assign ===
=== On Re-Assign ===
 
<pre>
my $txn = $self-&gt;TransactionObj;
my $txn = $self->TransactionObj;
return 0 unless $txn-&gt;Type eq "Set";
return 0 unless $txn->Type eq "Set";
return 0 unless $txn-&gt;Field eq "Owner";
return 0 unless $txn->Field eq "Owner";
return 0 if $txn-&gt;OldValue == $txn-&gt;Creator;
return 0 if $txn->OldValue == $txn->Creator;
return 0 if $txn-&gt;NewValue == $txn-&gt;Creator;
return 0 if $txn->NewValue == $txn->Creator;
return 1;
return 1;
</pre>


=== Checks with acting user (actor) ===
=== Checks with acting user (actor) ===
 
<pre>
  my $actor = $self-&gt;TransactionObj-&gt;CreatorObj;
my $actor = $self->TransactionObj->CreatorObj;
</pre>


=== On action by privileged ===
=== On action by privileged ===
 
<pre>
my $actor = $self-&gt;TransactionObj-&gt;CreatorObj;
my $actor = $self->TransactionObj->CreatorObj;
return 1 if $actor-&gt;Privileged;
return 1 if $actor->Privileged;
return 0;
return 0;
</pre>


=== On owner's action ===
=== On owner's action ===
 
<pre>
my $actor = $self-&gt;TransactionObj-&gt;CreatorObj;
my $actor = $self->TransactionObj->CreatorObj;
my $owner = $self-&gt;TicketObj-&gt;OwnerObj;
my $owner = $self->TicketObj->OwnerObj;
return 1 unless $actor-&gt;id == $owner->id;
return 1 unless $actor->id == $owner->id;
return 0;
return 0;
</pre>


== Checks with watchers and groups ==
== Checks with watchers and groups ==


=== When particular email address is in requestors ===
=== When particular email address is in requestors ===
 
<pre>
return 1 if $self-&gt;TicketObj-&gt;IsWatcher(
return 1 if $self->TicketObj->IsWatcher(
    Type =&gt; 'Requestor', Email =&gt; 'foo@bar.com'
    Type => 'Requestor', Email => 'foo@bar.com'
);
);
return 0;
return 0;
</pre>


=== When actor is member of one or more particular groups ===
=== When actor is member of one or more particular groups ===
<pre>
my @enforced_groups = ("Group 1","Group 2","etc");


my @enforced_groups = ("Group 1","Group 2","etc");
my $actor = $self->TransactionObj->CreatorObj;
my $actor = $self-&gt;TransactionObj-&gt;CreatorObj;


foreach my $gname (@enforced_groups) {
foreach my $gname (@enforced_groups) {
  my $group = RT::Group-&gt;new( $self->CurrentUser );
  my $group = RT::Group->new( $self->CurrentUser );
  $group-&gt;LoadUserDefinedGroup( $gname );
  $group->LoadUserDefinedGroup( $gname );
  next unless $group->id;
  next unless $group->id;


  return 1 if $group->HasMemberRecursively( $actor->id );
  return 1 if $group->HasMemberRecursively( $actor->id );
}
}
return 0;
return 0;
</pre>


=== Owner is not in the group ===
=== Owner is not in the group ===
<pre>
my $in_group = 'SupportManagers';
my $owner = $self->TicketObj->OwnerObj;
my $group = RT::Group->new( $self->CurrentUser );
$group->LoadUserDefinedGroup( $in_group );
return 0 if $group->HasMemberRecursively( $owner->id );


my $in_group = 'SupportManagers';
return 1;
</pre>
my $owner = $self-&gt;TicketObj-&gt;OwnerObj;
my $group = RT::Group-&gt;new( $self->CurrentUser );
$group->LoadUserDefinedGroup( $in_group );
return 0 if $group-&gt;HasMemberRecursively( $owner->id );
return 1;


== Checks with Custom Fields ==
== Checks with Custom Fields ==
Line 209: Line 235:
=== When current custom field value is X ===
=== When current custom field value is X ===


  <nowiki>
<pre>
        my $Ticket = $self-&gt;TicketObj;
my $Ticket = $self->TicketObj;
       
 
        return 0 unless $self->TicketObj-&gt;FirstCustomFieldValue('CustomFieldName') eq 'X';
return 0 unless $self->TicketObj->FirstCustomFieldValue('CustomFieldName') eq 'X';
        return 1;
return 1;
      </nowiki>
</pre>


=== On CustomField change ===
=== On CustomField change ===
 
<pre>
  return 0 unless $self->TransactionObj->Type eq 'CustomField';
return 0 unless $self->TransactionObj->Type eq 'CustomField';
  return 1;
return 1;
</pre>


=== On CustomField 'X' change ===
=== On CustomField 'X' change ===
<pre>
return 0 unless $self->TransactionObj->Type eq 'CustomField';


  return 0 unless $self->TransactionObj->Type eq 'CustomField';
my $cf = RT::CustomField->new( $self->CurrentUser );
$cf->Load( $self->TransactionObj->Field );
return 0 unless $cf->Name eq 'X';


  my $cf = RT::CustomField->new( $self->CurrentUser );
return 1;
  $cf->Load( $self->TransactionObj->Field );
</pre>
  return 0 unless $cf->Name eq 'X';
 
  return 1;


=== On CustomField 'X' change from 'A' to 'B' ===
=== On CustomField 'X' change from 'A' to 'B' ===
<pre>
my $txn = $self->TransactionObj;
return 0 unless $txn->Type eq 'CustomField';


  my $txn = $self->TransactionObj;
my $cf = RT::CustomField->new( $self->CurrentUser );
  return 0 unless $txn->Type eq 'CustomField';
$cf->Load( $txn->Field );
return 0 unless $cf->Name eq 'X';


  my $cf = RT::CustomField->new( $self->CurrentUser );
return 0 unless $txn->OldValue eq 'A';
  $cf->Load( $txn->Field );
return 0 unless $txn->NewValue eq 'B';
  return 0 unless $cf->Name eq 'X';


  return 0 unless $txn->OldValue eq 'A';
return 1;
  return 0 unless $txn->NewValue eq 'B';
</pre>
 
  return 1;


=== When Custom Field 'X' is set to 'A' ===
=== When Custom Field 'X' is set to 'A' ===
<pre>
my $txn = $self->TransactionObj;
my $type = $txn->Type;
if ( $type eq 'Create' ) {
    # CF can be set on create
    return 0 unless $self->TicketObj->FirstCustomFieldValue('X') eq 'A';
} elsif ( $type eq 'CustomField' ) {
    # CF can be changed later
    my $cf = RT::CustomField->new( $self->CurrentUser );
    $cf->Load( $txn->Field );
    return 0 unless $cf->Name eq 'X';


  my $txn = $self->TransactionObj;
    return 0 unless $txn->NewValue eq 'A';
  my $type = $txn->Type;
} else {
  if ( $type eq 'Create' ) {
    return 0;
      # CF can be set on create
}
      return 0 unless $self->TicketObj->FirstCustomFieldValue('X') eq 'A';
return 1;
  } elsif ( $type eq 'CustomField' ) {
</pre>
      # CF can be changed later
      my $cf = RT::CustomField->new( $self->CurrentUser );
      $cf->Load( $txn->Field );
      return 0 unless $cf->Name eq 'X';
      return 0 unless $txn->NewValue eq 'A';
} else {
      return 0;
}
return 1;


=== On Correspond, set Custom Field "X" to "0" ===
=== On Correspond, set Custom Field "X" to "0" ===
<pre>
return 1;


return 1;
my $ticket = $self->TicketObj;
my $cf_obj = RT::CustomField->new($RT::SystemUser);
my $cf_name = "X";
my $cf_value = "0";


my $ticket = $self->TicketObj;
$cf_obj->LoadByName( Name => $cf_name );
my $cf_obj = RT::CustomField->new($RT::SystemUser);
$RT::Logger->debug( "Loaded \$cf_obj->Name = ". $cf_obj->Name() ."\n" );
my $cf_name = "X";
$ticket->AddCustomFieldValue( Field=>$cf_obj, Value=>$cf_value,
my $cf_value = "0";
RecordTransaction=>0 );
$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;
return 1;
</pre>


== UserDefined2 (use with rt-crontool) ==
== UserDefined2 (use with rt-crontool) ==
create a file UserDefined2.pm in lib/RT/Condition
create a file UserDefined2.pm in lib/RT/Condition
package RT::Condition::UserDefined2;
<pre>
use base 'RT::Condition';
package RT::Condition::UserDefined2;
use strict;
use base 'RT::Condition';
=head2 IsApplicable
use strict;
=head2 IsApplicable
=cut
 
=cut
sub IsApplicable {
 
    my $self = shift;
sub IsApplicable {
    local $@;
    my $self = shift;
    my $retval = eval { $self->Argument; }; warn $@ if $@;
    local $@;
    return ($retval);
    my $retval = eval { $self->Argument; }; warn $@ if $@;
}
    return ($retval);
}
RT::Base->_ImportOverlays();
 
1;
RT::Base->_ImportOverlays();
1;
</pre>
 
With this you have a powerful way to check a customized condition. You can use it like that:
With this you have a powerful way to check a customized condition. You can use it like that:
bin/rt-crontool --verbose --log debug --search RT::Search::ActiveTicketsInQueue --search-arg Support --condition RT::Condition::UserDefined2 --condition-arg "if($self->TicketObj->Priority == 4){return(1);}else {return(undef);}" --action RT::Action::SetPriority --action-arg 7
<pre>
bin/rt-crontool --verbose --log debug --search RT::Search::ActiveTicketsInQueue --search-arg Support --condition RT::Condition::UserDefined2 --condition-arg "if($self->TicketObj->Priority == 4){return(1);}else {return(undef);}" --action RT::Action::SetPriority --action-arg 7
</pre>
 
This example searches all tickets in queue Support, checks if the priority is 4 and sets the priority to 7. You may use arbitrary perl-code for the condition.
This example searches all tickets in queue Support, checks if the priority is 4 and sets the priority to 7. You may use arbitrary perl-code for the condition.
== add your own conditions ==
== add your own conditions ==


...
...

Latest revision as of 13:50, 15 August 2016

Introduction

This page introduce you with some code that can be used in Conditions and is part of CodeSnippets series of articles.

Custom conditions specifics

Read WriteCustomCondition to understand basics of writing conditions.

Code Snippets

Here is list of various custom conditions you can use.

On Create and variants

return 0 unless $self->TransactionObj->Type eq "Create";
return 1;

On Create, but queue is not 'xxx'

return 0 unless $self->TransactionObj->Type eq "Create";
return 0 if $self->TicketObj->QueueObj->Name eq "xxx";
return 1;

On Create with status resolved

If you create Ticket with status resolved then standard RT condition OnResolve wouldn't trigger.

return 0 unless $self->TransactionObj->Type eq "Create";
return 0 unless $self->TicketObj->Status eq 'resolved';
return 1;

On Correspond/Comment and variants

return 0 unless $self->TransactionObj->Type eq "Correspond";
return 1;

On Correspond to Unowned Ticket

return 0 unless $self->TransactionObj->Type eq "Correspond";
return 0 unless $self->TicketObj->Owner == $RT::Nobody->id;
return 1;

Can be used in "On Correspond to Unowned Notify Admin Ccs With Admin Correspondence".

On Status Change and variants

For historical reasons it's more correct to write this condition like this:

my $txn = $self->TransactionObj;
my $type = $txn->Type;
return 0 unless $type eq "Status"
    || ( $type eq 'Set' && $txn->Field eq 'Status');
return 1;

On Status Change to "resolved"

my $txn = $self->TransactionObj;
my $type = $txn->Type;
return 0 unless $type eq "Status"
    || ( $type eq 'Set' && $txn->Field eq 'Status');

return 0 unless $txn->NewValue eq "resolved";
return 1;

on Status Change from "new" to "open"

my $txn = $self->TransactionObj;
my $type = $txn->Type;
return 0 unless $type eq "Status"
    || ( $type eq 'Set' && $txn->Field eq 'Status');

return 0 unless $txn->OldValue eq "new";
return 0 unless $txn->NewValue eq "open";
return 1;

On Queue Change

return 0 unless $self->TransactionObj->Type eq "Set";
return 0 unless $self->TransactionObj->Field eq "Queue";
return 1;

On Owner Change and variants

return 0 unless $self->TransactionObj->Type eq "Set";
return 0 unless $self->TransactionObj->Field eq "Owner";
return 1;

On Owner Change from Nobody to Any

my $txn = $self->TransactionObj;
return 0 unless $txn->Type eq "Set";
return 0 unless $txn->Field eq "Owner";
return 0 unless $txn->OldValue == $RT::Nobody->id;
return 1;

On Take

my $txn = $self->TransactionObj;
return 0 unless $txn->Type eq "Set";
return 0 unless $txn->Field eq "Owner";
return 0 unless $txn->OldValue == $RT::Nobody->id;
return 0 unless $txn->NewValue == $txn->Creator;
return 1;

On Steal

See also OnStealEnhanced

my $txn = $self->TransactionObj;
return 0 unless $txn->Type eq "Set";
return 0 unless $txn->Field eq "Owner";
return 0 if $txn->OldValue == $RT::Nobody->id;
return 0 unless $txn->NewValue == $txn->Creator;
return 1;

On Give

my $txn = $self->TransactionObj;
return 0 unless $txn->Type eq "Set";
return 0 unless $txn->Field eq "Owner";
return 0 unless $txn->OldValue == $RT::Nobody->id;
return 0 if $txn->NewValue == $txn->Creator;
return 1;

On Give Up

my $txn = $self->TransactionObj;
return 0 unless $txn->Type eq "Set";
return 0 unless $txn->Field eq "Owner";
return 0 unless $txn->OldValue == $txn->Creator;
return 0 unless $txn->NewValue == $RT::Nobody->id;
return 1;

On Assign

my $txn = $self->TransactionObj;
return 0 unless $txn->Type eq "Set";
return 0 unless $txn->Field eq "Owner";
return 0 unless $txn->OldValue == $RT::Nobody->id;
return 0 if $txn->NewValue == $txn->Creator;
return 1;

On Re-Assign

my $txn = $self->TransactionObj;
return 0 unless $txn->Type eq "Set";
return 0 unless $txn->Field eq "Owner";
return 0 if $txn->OldValue == $txn->Creator;
return 0 if $txn->NewValue == $txn->Creator;
return 1;

Checks with acting user (actor)

my $actor = $self->TransactionObj->CreatorObj;

On action by privileged

my $actor = $self->TransactionObj->CreatorObj;
return 1 if $actor->Privileged;
return 0;

On owner's action

my $actor = $self->TransactionObj->CreatorObj;
my $owner = $self->TicketObj->OwnerObj;
return 1 unless $actor->id == $owner->id;
return 0;

Checks with watchers and groups

When particular email address is in requestors

return 1 if $self->TicketObj->IsWatcher(
    Type => 'Requestor', Email => 'foo@bar.com'
);
return 0;

When actor is member of one or more particular groups

my @enforced_groups = ("Group 1","Group 2","etc");

my $actor = $self->TransactionObj->CreatorObj;

foreach my $gname (@enforced_groups) {
  my $group = RT::Group->new( $self->CurrentUser );
  $group->LoadUserDefinedGroup( $gname );
  next unless $group->id;

  return 1 if $group->HasMemberRecursively( $actor->id );
}
return 0;

Owner is not in the group

my $in_group = 'SupportManagers';

my $owner = $self->TicketObj->OwnerObj;
my $group = RT::Group->new( $self->CurrentUser );
$group->LoadUserDefinedGroup( $in_group );
return 0 if $group->HasMemberRecursively( $owner->id );

return 1;

Checks with Custom Fields

When current custom field value is X

my $Ticket = $self->TicketObj;

return 0 unless $self->TicketObj->FirstCustomFieldValue('CustomFieldName') eq 'X';
return 1;

On CustomField change

return 0 unless $self->TransactionObj->Type eq 'CustomField';
return 1;

On CustomField 'X' change

return 0 unless $self->TransactionObj->Type eq 'CustomField';

my $cf = RT::CustomField->new( $self->CurrentUser );
$cf->Load( $self->TransactionObj->Field );
return 0 unless $cf->Name eq 'X';

return 1;

On CustomField 'X' change from 'A' to 'B'

my $txn = $self->TransactionObj;
return 0 unless $txn->Type eq 'CustomField';

my $cf = RT::CustomField->new( $self->CurrentUser );
$cf->Load( $txn->Field );
return 0 unless $cf->Name eq 'X';

return 0 unless $txn->OldValue eq 'A';
return 0 unless $txn->NewValue eq 'B';

return 1;

When Custom Field 'X' is set to 'A'

my $txn = $self->TransactionObj;
my $type = $txn->Type;
if ( $type eq 'Create' ) {
    # CF can be set on create
    return 0 unless $self->TicketObj->FirstCustomFieldValue('X') eq 'A';
} elsif ( $type eq 'CustomField' ) {
    # CF can be changed later
    my $cf = RT::CustomField->new( $self->CurrentUser );
    $cf->Load( $txn->Field );
    return 0 unless $cf->Name eq 'X';

    return 0 unless $txn->NewValue eq 'A';
} else {
     return 0;
}
return 1;

On Correspond, set Custom Field "X" to "0"

return 1;

my $ticket = $self->TicketObj;
my $cf_obj = RT::CustomField->new($RT::SystemUser);
my $cf_name = "X";
my $cf_value = "0";

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

UserDefined2 (use with rt-crontool)

create a file UserDefined2.pm in lib/RT/Condition

package RT::Condition::UserDefined2;
use base 'RT::Condition';
use strict;
=head2 IsApplicable

=cut

sub IsApplicable {
    my $self = shift;
    local $@;
    my $retval = eval { $self->Argument; }; warn $@ if $@;
    return ($retval);
}

RT::Base->_ImportOverlays();
1;

With this you have a powerful way to check a customized condition. You can use it like that:

bin/rt-crontool --verbose --log debug --search RT::Search::ActiveTicketsInQueue --search-arg Support --condition RT::Condition::UserDefined2 --condition-arg "if($self->TicketObj->Priority == 4){return(1);}else {return(undef);}" --action RT::Action::SetPriority --action-arg 7

This example searches all tickets in queue Support, checks if the priority is 4 and sets the priority to 7. You may use arbitrary perl-code for the condition.

add your own conditions

...