%# Politicians are the same all over.  They promise to build a bridge even
%# where there is no river.
%# 		-- Nikita Khrushchev
<%INIT>
my $approvals_queue = RT::Queue->new($session{'CurrentUser'});
$approvals_queue->Load('___Approvals');
return if $approvals_queue->Id;

my ($val, $msg) = $approvals_queue->Create(
    Name        => '___Approvals',
    Description => 'A system-internal queue for the approvals system',
    Disabled    => 1,
);

Abort($msg) unless ($val);

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

Greetings,

There is a new item pending your approval: "{$Ticket->Subject()}", 
a summary of which appears below.

Please visit {$RT::WebURL}Approvals/Display.html?id={$Ticket->id}
to approve or reject this ticket, or {$RT::WebURL}Approvals/ to
batch-process all your pending approvals.

-------------------------------------------------------------------------
{$Transaction->Content()}
'
    },
);

foreach my $item (@templates) {
    my $new_entry = RT::Template->new($session{CurrentUser});
    $new_entry->Load($item->{Name});
    $new_entry->Create(%$item) unless $new_entry->Id;
}
# }}}

# Scrips {{{

my @scrips = (
    {
        Description    => "When an approval ticket is created, notify the Owner and AdminCc of the item awaiting their approval", # loc
        Queue          => $approvals_queue->Id,
        ScripCondition => 'On Create',
        ScripAction    => 'Notify AdminCcs',
        Template       => 'New Pending Approval'
    },
    {
        Description	       => "If an approval is rejected, reject the original and delete pending approvals",	# loc
        Queue                  => $approvals_queue->Id,
        ScripCondition         => 'On Status Change',
        ScripAction            => 'User Defined',
        CustomCommitCode       => q[
# ------------------------------------------------------------------- #
return(1) unless ( lc($self->TransactionObj->NewValue) eq "rejected" or
	           lc($self->TransactionObj->NewValue) eq "deleted" );

my $links = $self->TicketObj->DependedOnBy;
foreach my $link (@{ $links->ItemsArrayRef }) {
    my $obj = $link->BaseObj;
    if ($obj->QueueObj->IsActiveStatus($obj->Status)) {
	if ($obj->Type eq 'ticket') {
	    $obj->Correspond(
		Content	=> $self->loc("Your request was rejected."),
	    );
	    $obj->SetStatus(
		Status	=> 'rejected',
		Force	=> 1,
	    );
	}
	else {
	    $obj->SetStatus(
		Status	=> 'deleted',
		Force	=> 1,
	    );
	}
    }
}

$links = $self->TicketObj->DependsOn;
foreach my $link (@{ $links->ItemsArrayRef }) {
    my $obj = $link->TargetObj;
    if ($obj->QueueObj->IsActiveStatus($obj->Status)) {
	$obj->SetStatus(
	    Status	=> 'deleted',
	    Force	=> 1,
	);
    }
}

return 1;
# ------------------------------------------------------------------- #
	],
        CustomPrepareCode => '1',
        Template          => 'AdminComment',
    },
    {
        Description	  => "When a ticket has been approved by any approver, add correspondence to the original ticket", # loc
        Queue             => $approvals_queue->Id,
        ScripCondition    => 'On Resolve',
        ScripAction       => 'User Defined',
        CustomPrepareCode => 'return(1);',
        CustomCommitCode  => q[
# ------------------------------------------------------------------- #
return(1) unless ($self->TicketObj->Type eq 'approval');

foreach my $obj ($self->TicketObj->AllDependedOnBy( Type => 'ticket' )) {
    $obj->Correspond(
	Content => $self->loc(
	    "Your request has been approved by [_1]. Other approvals may still be pending.", # loc
	    $self->TransactionObj->CreatorObj->Name,
	) . "\n" . $self->loc(
	    "Approver's notes: [_1]", # loc
	    $self->TicketObj->Transactions->Last->Content,
	),
	_reopen	=> 0,
    );
}

return 1;
# ------------------------------------------------------------------- #
	],
	Template => 'AdminComment'
    },
    {
        Description	  => "When a ticket has been approved by all approvers, add correspondence to the original ticket", # loc
        Queue             => $approvals_queue->Id,
        ScripCondition    => 'On Resolve',
        ScripAction       => 'User Defined',
        CustomPrepareCode => 'return(1);',
        CustomCommitCode  => q[
# ------------------------------------------------------------------- #
# Find all the tickets that depend on this (that this is approving)

my $Ticket = $self->TicketObj;
my @TOP    = $Ticket->AllDependedOnBy( Type => 'ticket' );
my $links  = $Ticket->DependedOnBy;

while (my $link = $links->Next) {
    my $obj = $link->BaseObj;
    next if ($obj->HasUnresolvedDependencies( Type => 'approval' ));

    if ($obj->Type eq 'ticket') {
	$obj->Correspond(
	    Content	=> $self->loc("Your request has been approved."),
	    _reopen	=> 0,
	);
    }
    elsif ($obj->Type eq 'code') {
	my $code = $obj->Transactions->First->Content;
	my $rv;

	foreach my $TOP (@TOP) {
	    local $@;
	    $rv++ if eval $code;
	    $RT::Logger->error("Cannot eval code: $@") if $@;
	}

	if ($rv or !@TOP) {
	    $obj->SetStatus(
		Status	=> 'resolved',
		Force	=> 1,
	    );
	}
	else {
	    $obj->SetStatus(
		Status	=> 'rejected',
		Force	=> 1,
	    );
	}
    }
}

return 1;
# ------------------------------------------------------------------- #
	],
        Template    => 'AdminComment',
    },
);

# }}}

foreach my $item (@scrips) {
    my $new_entry = RT::Scrip->new($session{CurrentUser});
    $new_entry->Load($item->{Name});
    $new_entry->Create(%$item) unless $new_entry->Id;
}

</%INIT>
