Difference between revisions of "ManualApprovals"

From Request Tracker Wiki
Jump to navigation Jump to search
Line 11: Line 11:
== NAME ==
== NAME ==


RT::Action::CreateTickets - Create one or more tickets according to an externally supplied template
RT::Action::CreateTickets - Create one or more tickets according to an externally supplied template


== SYNOPSIS ==
== SYNOPSIS ==


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


== DESCRIPTION ==
== DESCRIPTION ==
Line 30: Line 30:
[[CreateTickets]] uses the RT template configured in the scrip as a template for an ordered set of tickets to create. The basic format is as follows:
[[CreateTickets]] uses the RT template configured in the scrip as a template for an ordered set of tickets to create. The basic format is as follows:


<pre>===Create-Ticket: identifier
<pre>===Create-Ticket: identifier
Param: Value
Param: Value
Param2: Value
Param2: Value
Param3: Value
Param3: Value
Content: Blah
Content: Blah
blah
blah
blah
blah
ENDOFCONTENT
ENDOFCONTENT
===Create-Ticket: id2
===Create-Ticket: id2
Param: Value
Param: Value
Content: Blah
Content: Blah
ENDOFCONTENT</pre>
ENDOFCONTENT</pre>


As shown, you can put one or more <pre>===Create-Ticket:</pre> sections in a template. Each <pre>===Create-Ticket:</pre> 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 <pre>===Create-Ticket:</pre> boundary.
As shown, you can put one or more <code>===Create-Ticket:</code> sections in a template. Each <code>===Create-Ticket:</code> 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 <code>===Create-Ticket:</code> boundary.


Note that each Value must come right after the Param on the same line. The Content: param can extend over multiple lines, but the text of the first line must start right after Content:. Don't try to start your <pre>Content:</pre> section with a newline.
Note that each Value must come right after the Param on the same line. The Content: param can extend over multiple lines, but the text of the first line must start right after Content:. Don't try to start your <code>Content:</code> section with a newline.


After each ticket is created, it's stuffed into a hash called <pre>%Tickets</pre> making it available during the creation of other tickets during the same ScripAction. The hash key for each ticket is <pre>create-[identifier]</pre>, where <pre>[identifier]</pre> is the value you put after <pre>===Create-Ticket:</pre>.  The hash is prepopulated with the ticket which triggered the ScripAction as <pre>$Tickets{'TOP'}</pre>. You can also access that ticket using the shorthand TOP.
After each ticket is created, it's stuffed into a hash called <code>%Tickets</code> making it available during the creation of other tickets during the same ScripAction. The hash key for each ticket is <code>create-[identifier]</code>, where <code>[identifier]</code> is the value you put after <code>===Create-Ticket:</code>.  The hash is prepopulated with the ticket which triggered the ScripAction as <code>$Tickets{'TOP'}</code>. You can also access that ticket using the shorthand TOP.


A simple example:
A simple example:


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


A convoluted example:
A convoluted example:


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


    my $groups = RT::Groups->new(RT->SystemUser);
  my $groups = RT::Groups->new(RT->SystemUser);
    $groups->LimitToUserDefinedGroups();
  $groups->LimitToUserDefinedGroups();
    $groups->Limit(FIELD => "Name", OPERATOR => "=", VALUE => $name, CASESENSITIVE => 0);
  $groups->Limit(FIELD => "Name", OPERATOR => "=", VALUE => $name, CASESENSITIVE => 0);
    $groups->WithMember($TransactionObj->CreatorObj->Id);
  $groups->WithMember($TransactionObj->CreatorObj->Id);


    my $groupid = $groups->First->Id;
  my $groupid = $groups->First->Id;


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


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


=== Acceptable Fields ===
=== Acceptable Fields ===
Line 112: Line 112:
A complete list of acceptable fields:
A complete list of acceptable fields:


  <pre>*  Queue          => Name or id# of a queue
<pre> *  Queue          => Name or id# of a queue
      Subject        => A text string
    Subject        => A text string
    ! Status          => A valid status. Defaults to 'new'
  ! Status          => A valid status. Defaults to 'new'
      Due            => Dates can be specified in seconds since the epoch
    Due            => Dates can be specified in seconds since the epoch
                          to be handled literally or in a semi-free textual
                      to be handled literally or in a semi-free textual
                          format which RT will attempt to parse.
                      format which RT will attempt to parse.
      Starts          =>
    Starts          =>
      Started        =>
    Started        =>
      Resolved        =>
    Resolved        =>
      Owner          => Username or id of an RT user who can and should own
    Owner          => Username or id of an RT user who can and should own
                          this ticket; forces the owner if necessary
                      this ticket; forces the owner if necessary
  +  Requestor      => Email address
+  Requestor      => Email address
  +  Cc              => Email address
+  Cc              => Email address
  +  AdminCc        => Email address
+  AdminCc        => Email address
  +  RequestorGroup  => Group name
+  RequestorGroup  => Group name
  +  CcGroup        => Group name
+  CcGroup        => Group name
  +  AdminCcGroup    => Group name
+  AdminCcGroup    => Group name
      TimeWorked      =>
    TimeWorked      =>
      TimeEstimated  =>
    TimeEstimated  =>
      TimeLeft        =>
    TimeLeft        =>
      InitialPriority =>
    InitialPriority =>
      FinalPriority  =>
    FinalPriority  =>
      Type            =>
    Type            =>
    +! DependsOn      =>
+! DependsOn      =>
    +! DependedOnBy    =>
+! DependedOnBy    =>
    +! RefersTo        =>
+! RefersTo        =>
    +! ReferredToBy    =>
+! ReferredToBy    =>
    +! Members        =>
+! Members        =>
    +! MemberOf        =>
+! MemberOf        =>
      Content        => Content. Can extend to multiple lines. Everything
    Content        => Content. Can extend to multiple lines. Everything
                          within a template after a Content: header is treated
                      within a template after a Content: header is treated
                          as content until we hit a line containing only
                      as content until we hit a line containing only
                          ENDOFCONTENT
                      ENDOFCONTENT
      ContentType    => the content-type of the Content field.  Defaults to
    ContentType    => the content-type of the Content field.  Defaults to
                          'text/plain'
                      'text/plain'
      UpdateType      => 'correspond' or 'comment'; used in conjunction with
    UpdateType      => 'correspond' or 'comment'; used in conjunction with
                          'content' if this is an update.  Defaults to
                      'content' if this is an update.  Defaults to
                          'correspond'
                      'correspond'


      CustomField-<id#> => custom field value
    CustomField-<id#> => custom field value
      CF-name          => custom field value
    CF-name          => custom field value
      CustomField-name  => custom field value</pre>
    CustomField-name  => custom field value</pre>


Fields marked with an <pre>*</pre> are required.
Fields marked with an <code>*</code> are required.


Fields marked with a <pre>+</pre> may have multiple values, simply by repeating the fieldname on a new line with an additional value.
Fields marked with a <code>+</code> may have multiple values, simply by repeating the fieldname on a new line with an additional value.


Fields marked with a <pre>!</pre> have processing postponed until after all tickets in the same actions are created.  Except for <pre>Status</pre>, those fields can also take a ticket name within the same action (i.e. the identifiers after <pre>===Create-Ticket:</pre>), instead of raw ticket ID numbers.
Fields marked with a <code>!</code> have processing postponed until after all tickets in the same actions are created.  Except for <code>Status</code>, those fields can also take a ticket name within the same action (i.e. the identifiers after <code>===Create-Ticket:</code>), instead of raw ticket ID numbers.


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


For another explanation, see [[ApprovalCreation]].
For another explanation, see [[ApprovalCreation]].

Revision as of 15:07, 21 March 2019

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

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:

NAME

RT::Action::CreateTickets - Create one or more tickets according to an externally supplied template

SYNOPSIS

===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

DESCRIPTION

The "CreateTickets" ScripAction allows you to create automated workflows in RT, creating new tickets in response to actions and conditions from other tickets.

Format

CreateTickets uses the RT template configured in the scrip 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

As shown, you can put one or more ===Create-Ticket: sections in a template. 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.

Note that each Value must come right after the Param on the same line. The Content: param can extend over multiple lines, but the text of the first line must start right after Content:. Don't try to start your Content: section with a newline.

After each ticket is created, it's stuffed into a hash called %Tickets making it available during the creation of other tickets during the same ScripAction. The hash key for each ticket is create-[identifier], where [identifier] is the value you put after ===Create-Ticket:. 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
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->LimitToUserDefinedGroups();
   $groups->Limit(FIELD => "Name", OPERATOR => "=", VALUE => $name, CASESENSITIVE => 0);
   $groups->WithMember($TransactionObj->CreatorObj->Id);

   my $groupid = $groups->First->Id;

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

    our @admins;
    while (my $admin = $adminccs->Next) {
        push (@admins, $admin->EmailAddress);
    }
}
Queue: ___Approvals
Type: approval
AdminCc: {join ("\nAdminCc: ",@admins) }
Depended-On-By: TOP
Refers-To: TOP
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}
Blah
Blah
ENDOFCONTENT
===Create-Ticket: two
Subject: Manager approval
Type: approval
Depended-On-By: TOP
Refers-To: {$Tickets{"create-approval"}->Id}
Queue: ___Approvals
Content-Type: text/plain
Content: Your approval is requred for this ticket, too.
ENDOFCONTENT

Acceptable Fields

A complete list of acceptable fields:

 *  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; forces the owner if necessary
+   Requestor       => Email address
+   Cc              => Email address
+   AdminCc         => Email address
+   RequestorGroup  => Group name
+   CcGroup         => Group name
+   AdminCcGroup    => Group name
    TimeWorked      =>
    TimeEstimated   =>
    TimeLeft        =>
    InitialPriority =>
    FinalPriority   =>
    Type            =>
 +! DependsOn       =>
 +! DependedOnBy    =>
 +! RefersTo        =>
 +! ReferredToBy    =>
 +! Members         =>
 +! MemberOf        =>
    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.  Defaults to
                       'text/plain'
    UpdateType      => 'correspond' or 'comment'; used in conjunction with
                       'content' if this is an update.  Defaults to
                       'correspond'

    CustomField-<id#> => custom field value
    CF-name           => custom field value
    CustomField-name  => custom field value

Fields marked with an * are required.

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

Fields marked with a ! have processing postponed until 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 hyphens 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