Request Tracker serialized workflow

RT offers many ways to manage workflow, but most of them create a separate ticket for each part of the workflow.  The tasks at my company are mostly serialized:  a request comes in, is worked on by person A, who hands it off to person B, who hands it to person C, who closes the request.  Opening a separate ticket for each of these isn’t efficient.  (The situation is different for parallelized tasks.)  I want a method to easily pass tickets from one person to the next.

I could simply tell people “When you complete your task, assign this ticket to person X.”  It’s a small company, and everybody knows the workflow for the tasks that they’re involved in.  Human beings are fallible, though, and I don’t want customer service lapses because people to forget to assign the ticket to the next person.  New employees will be immediately overwhelmed by the number and complexity of our workflow, and the system needs to take that away.

Additionally, most of our ticket reassignment occurs when a task is complete.  The ticket might contain IP addresses, phone numbers, or other information, but ultimately, the user should just be able to click a button that says “Task X is complete.”  RT should automatically reassign the ticket to the next person.

To create this serialized, I created a separate queue for each type of routine task.  While the company does several different things, our routine tasks can be lumped into several different general categories: new provisioning of a couple different types, service shutdown, and so on.  Then I talked to the people involved to see how exactly each type of task moved through the company.  (This was a useful exercise in itself: once I presented my findings to the people involved, they saw ways to streamline their work.)

Then I created RT CustomFields for each task completion.  For example, one common task is a Port.  When the Port is complete, the ticket should go to Billing.  I created a CustomField called “Port Completion,” of a type “Select One Value.”  The values are “Error” and “Ported and Routed.”

Then we need a Scrip to check to see if this CustomField is freshly set to “Ported and Routed” in a particular transaction.  I found a Scrip that claimed to do this, but it didn’t work for me.  I wrote the mailing list giving all the settings I used for the Scrip, the entire Scrip, and my RT version and platform.  Kenn Crocker was kind enough to send me a complete replacement for the failed Scrip.  Use this Scrip in the queue where you want the automatic assignment to occur.

Name: Set Owner on CF
Condition: User-Defined
Action: User-Defined
Template: Blank
Stage: TransactionBatch

The Custom Condition is:

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 => "Port Completion");
return 0 unless $cf->id;
if  ($trans->Field == $cf->id &&
$trans->NewValue eq "Ported and Routed")
return 1;
return 0;

The Custom Action sets the ticket owner.  Put the correct user ID into the quotes in line 2:

my $ticket = $self->TicketObj;
my $ownerid = "userID";
return 1;

You need the custom cleanup code, even though it’s trivial:

return 1;

The annoying thing about this approach is that you need to replicate this Scrip for every automatic reassignment in every queue.  It’s not difficult, but it is tedious and takes testing.  It puts the work on the RT administrator rather than on the staff.  Personally, I’d much rather administer RT than do all of the fiddly paperwork involved in some of the other jobs!

Stalk me on social media