From Request Tracker Wiki
Jump to: navigation, search

Prev: ManualScrips --- Up: UserManual --- Next: RTGlossary

Appendix 5

Creating Approvals

Approvals are a useful way to get tickets OK'd by management without creating a new system. A supervisor's approval can be a ticket; another ticket can depend on that ticket being resolved.

The custom programming to create tickets involves the Create Tickets scrip action and a template that asks a supervisor to look at the ticket asking for approval.

Here is an example of the process by RT's head honcho, Jesse Vincent:



Create one or more tickets according to an externally supplied template.


===Create-Ticket: codereview Subject: Code review for {$Tickets{'TOP'}->Subject} Depended-On-By: TOP Content: Someone has created a ticket. you should review and approve it, so they can finish their work ENDOFCONTENT


Using the "CreateTickets" ScripAction and mandatory dependencies, RT now has the ability to model complex workflow. When a ticket is created in a queue that has a "CreateTickets" scripaction, that ScripAction parses its "Template"


CreateTickets uses the template as a template for an ordered set of tickets to create. The basic format is as follows:

===Create-Ticket: identifier Param: Value Param2: Value Param3: Value Content: Blah blah blah ENDOFCONTENT ===Create-Ticket: id2 Param: Value Content: Blah ENDOFCONTENT

Each ===Create-Ticket: section is evaluated as its own Text::Template object, which means that you can embed snippets of perl inside the Text::Template using {} delimiters, but that such sections absolutely can not span a ===Create-Ticket boundary.

After each ticket is created, it's stuffed into a hash called %Tickets so as to be available during the creation of other tickets during the same ScripAction. The hash is prepopulated with the ticket which triggered the ScripAction as $Tickets{'TOP'}; you can also access that ticket using the shorthand $TOP.

A simple example:

===Create-Ticket: codereview Subject: Code review for {$Tickets{'TOP'}->Subject} Depended-On-By: TOP Queue: ___Approvals Type: approval Content: Someone has created a ticket. you should review and approve it, so they can finish their work ENDOFCONTENT

A convoluted example:

  ===Create-Ticket: approval
  { # Find out who the administrators of the group called "HR"
    # of which the creator of this ticket is a member
     my $name = "HR";

     my $groups = RT::Groups->new($RT::SystemUser);


        $groups->Limit(FIELD => "Name", OPERATOR => "=", VALUE => "$name");
     my $groupid = $groups->First->Id;

     my $adminccs = RT::Users->new($RT::SystemUser);
         Right => "AdminGroup",
         Object =>$groups->First,
         IncludeSystemRights => undef,
         IncludeSuperusers => 0,
         IncludeSubgroupMembers => 0,

      my @admins;
      while (my $admin = $adminccs->Next) {
          push (@admins, $admin->EmailAddress);
  Queue: Approvals
  Type: approval
  AdminCc: {join ("\nAdminCc: ",@admins) }
  Depended-On-By: {$Tickets{"TOP"}->Id}
  Refers-To: {$Tickets{"TOP"}->Id}
  Subject: Approval for ticket: {$Tickets{"TOP"}->Id} - {$Tickets{"TOP"}->Subject}
  Due: {time + 86400}
  Content-Type: text/plain
  Content: Your approval is requested for the ticket {$Tickets{"TOP"}->Id}: {$Tickets{"TOP"}->Subject}
  ===Create-Ticket: two
  Subject: Manager approval
  Depended-On-By: {$Tickets{"TOP"}->Id}
  Refers-On: {$Tickets{"approval"}->Id}
  Queue: Approvals

Content-Type: text/plain

     Your approval is requred for this ticket, too.


A complete list of acceptable fields for this beastie:

  • Queue => Name or id# of a queue Subject => A text string ! Status => A valid status. defaults to 'new' Due => Dates can be specified in seconds since the epoch to be handled literally or in a semi-free textual format which RT will attempt to parse. Starts => Started => Resolved => Owner => Username or id of an RT user who can and should own this ticket
    • Requestor => Email address
    • Cc => Email address
    • AdminCc => Email address TimeWorked => TimeEstimated => TimeLeft => InitialPriority => FinalPriority => Type => +! DependsOn => +! DependedOnBy => +! RefersTo => +! ReferredToBy => +! Parents => +! Children => Content => content. Can extend to multiple lines.

Everything within a template after a Content: header is treated as content until we hit a line containing only ENDOFCONTENT

ContentType => the content-type of the Content field

CustomField-<id#> => custom field value

Fields marked with an * are required. Fields marked with a + man have multiple values, simply by repeating the fieldname on a new line with an additional value.

Fields marked with a ! are postponed to be processed after all tickets in the same actions are created. Except for 'Status', those fields can also take a ticket name within the same action (i.e. the identifiers after ==Create-Ticket), instead of raw Ticket ID numbers.

When parsed, field names are converted to lowercase and have -s stripped. Refers-To, RefersTo, refersto, refers-to and r-e-f-er-s-tO will all be treated as the same thing.

For another explanation, see ApprovalCreation.

Prev: ManualApache --- Up: UserManual