[rt-devel] Approvals

Autrijus Tang autrijus at autrijus.org
Fri Aug 23 12:34:23 EDT 2002

On Fri, Aug 23, 2002 at 11:19:45AM -0400, Matt Zimmerman wrote:
> My employer has requested that I implement approval functionality in RT,
> where a ticket cannot be resolved until other RT users have verified and
> approved it.  I had planned to implement the requests for approval as
> separate tickets upon which the original ticket would depend.

You may wish to check out the 2.1.30 snapshot release in;

Which contains basic hooks and the approval mechanism.

The additional insertdata script below creates the logic used for
approvals and stuff, as part of development toward RT3.  Basically,
RT2.1.30 implements a 'strong dependency' system in which one
ticket cannot be resolved unless the one it dependents on is.

I've been assigned to grok all the approval stuff in the next few
days, so if you run into problem/ideas, feel free to post here and
maybe we can help each other a bit. :-)



#!/usr/bin/perl -w
# $Header: /raid/cvsroot/rt/sbin/Attic/insertdata,v 2002/01/28 05:27:15 jesse Exp $
# RT is (c) 1996-2002 Jesse Vincent (jesse at bestpractical.com);

use strict;
use vars qw($VERSION $Handle $Nobody $SystemUser $item);

use lib "!!RT_LIB_PATH!!";

#This drags in  RT's config.pm
# We do it in a begin block because RT::Handle needs to know the type to do its
# inheritance
    use RT;
use Carp;

use RT::User;
use RT::CurrentUser;
use RT::Scrip;
use RT::Template;

#connect to the db
require RT::Handle;
$RT::Handle = RT::Handle->new();

#Put together a current user object so we can create a User object
my $CurrentUser = new RT::CurrentUser();

#now that we bootstrapped that little bit, we can use the standard RT cli
# helpers  to do what we need

use RT::Interface::CLI qw(CleanEnv GetCurrentUser GetMessageContent);

#Clean out all the nasties from the environment

#Load etc/config.pm and drop privs

#Connect to the database and get RT::SystemUser and RT::Nobody loaded


# {{{ Queues
my $approvals_queue = RT::Queue->new($CurrentUser);
unless ($approvals_queue->Id){ 
my ($val, $msg) =$approvals_queue->Create(
              Name        => '___Approvals',
              Description => 'A system-internal queue for the approvals system',

unless ($val) {
        warn $msg ."\n";
# }}}

# {{{ Scrips

my @scrips = (

    {    # If a ticket in approvals is rejected,
           # reject the original request and attach a reply
           # also, delete all other pending approvals

       Description =>
"If an approval is rejected, reject the original and delete pending approvals",
       Queue          => $approvals_queue->Id,
       ScripCondition => 'User Defined',
       ScripAction    => 'User Defined',
                        CustomIsApplicableCode => '
         if ( $self->TransactionObj->Field eq "Status" && $self->TransactionObj->NewValue eq "Rejected" ) {
           return 1;
       else { return undef }
         CustomCommitCode => '
        my $links = $self->TicketObj->DependedOnBy;
        while (my $link = $links->Next) {
        my $obj = $link->BaseObj;
        my $pending_approvals = $obj->DependsOn;
        while (my $dependson = $pending_approvals->Next) {
                my $dep = $dependson->TargetObj;
                if ($dep->QueueObj->IsActiveStatus($dep->Status)) {
        $obj->Correspond( Content => loc("Your request was rejected") );
       CustomPrepareCode => '1',
       Template => 'AdminComment', },

    {  Description =>
"When a ticket has been approved by all approvers,".
" add correspondence to the original ticket",
       Queue          => $approvals_queue->Id,
       ScripCondition => 'On Resolve',
        CustomPrepareCode => 'return(1);',
        CustomCommitCode => '
        #Find all the tickets that depend on this (that this is approving)
        my $links = $self->TicketObj->DependedOnBy;
        while ( my $link = $links->Next ) {
            # the ticket that depends on this one
            my $obj = $link->BaseObj; 
            next unless ($obj->HasUnresolvedDependencies);
            $obj->Correspond( Content => loc("Your request has been approved.") );
       ScripAction    => 'User Defined',
       Template       => 'AdminComment', },
    {  Description =>
        "When a ticket has been approved by any approver,".
        "add correspondence to the original ticket",
       Queue          => $approvals_queue->Id,
       ScripCondition => 'On Resolve',
       ScripAction    => 'User Defined',
       CustomPrepareCode => 'return(1);',
       CustomCommitCode => '
        my $links = $self->TicketObj->DependedOnBy;
        while ( my $link = $links->Next ) {
            # the ticket that depends on this one
            my $obj = $link->BaseObj; 
            $obj->Correspond( Content => loc("Your request has been approved by [_1]. Other approvals may still be pending.",$self->TransactionObj->CreatorObj->Name) );
       Template       => 'AdminComment' },
    {  Description =>
                        "When an approval ticket is created, notify the owner and adminccs".
                        " of the item awaiting their approval",
       Queue          => $approvals_queue->Id,
       ScripCondition => 'On Create',
       ScripAction => 'Notify AdminCcs',
       Template => 'New Pending Approval'
    } );

# }}}

# {{{ Templates
my @templates = ( {
                        Name => "New Pending Approval",
                        Queue => $approvals_queue->Id,
                        Description => "Notify Owners and AdminCcs of new items pending their approval",
                        Content => "Subject: New item pending your approval

There is a new item pending your approval. I have no idea
what autrijus client wants here.


# }}}

print "Creating templates...";

use RT::Template;
for $item (@templates) {
    my $new_entry = RT::Template->new($CurrentUser);
    my $return    = $new_entry->Create(%$item);
    print $return. ".";
print "done.\n";

print "Creating scrips...";

use RT::Template;
for $item (@scrips) {
    my $new_entry = RT::Scrip->new($CurrentUser);
    my ($return,$cmsg)    = $new_entry->Create(%$item);
    print $return. ".";
    unless ($return)  {
        warn $cmsg;

        use Data::Dumper;
        #print scalar Dumper($item);

print "done.\n";



-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 187 bytes
Desc: not available
Url : http://pallas.eruditorum.org/pipermail/rt-devel/attachments/20020824/58cd8666/attachment.pgp

More information about the Rt-devel mailing list