=head1 NAME

  RT::Action::UpdatePriority

=head1 DESCRIPTION

UpdatePriority is a ScriptAction that updates the priority of a ticket
to match that of the queue it is in. UpdatePriority is supposed to be
called by an RT escalation tool, such as rt-crontool. It makes it
possible to move a ticket from one queue to another, and have the
ticket's priority updated.

Here's an example: Suppose you have tree queues. One where the tickets
are due in 7 days, one where they are due in 14 days and one where
they are due in 30 days. If you now wanted to move tickets from one
queue to another, the due date for the tickets would be wrong. You
would then run this ScriptAction to update the priority in the moved
tickets.

UpdatePriority will change the ticket's priority to satisfy this
equation:

priority =
(FinalPriority / DefaultDueIn) * (today - Created) + InitialPriority

=cut

package RT::Action::UpdatePriority;
require RT::Action::Generic;

use strict;

use vars qw(@ISA);
@ISA = qw(RT::Action::Generic);

# What does this Action do?
sub Describe {
    my $self = shift;
    return ref $self .
	" updates a ticket's priority to match that of the queue it is in";
}

use constant SECONDS_PER_DAY => 60 * 60 * 24;

sub Prepare {
    my $self = shift;
    my $final_priority = $self->TicketObj->QueueObj->FinalPriority();
    my $initial_priority = $self->TicketObj->QueueObj->InitialPriority();
    my $created = RT::Date->new($self->TicketObj->CurrentUser());
    $created->Set(Format => 'sql',
		  Value => $self->TicketObj->Created());
    my $priority = $self->TicketObj->Priority();
    my $default_due_in = $self->TicketObj->QueueObj->DefaultDueIn();
    my $due = $self->TicketObj->DueObj();
    my $today = RT::Date->new($self->TicketObj->CurrentUser());
    $today->SetToNow();

    return 0 if ($priority > $final_priority);

    # -1 means that the ticket has no due date at all. We leave such
    # tickets alone.
    return 0 if ($due->Unix == -1);

    my $diff_in_days = int($today->Diff($created) / SECONDS_PER_DAY);

    my $new_priority =
	int(($final_priority / $default_due_in) * $diff_in_days) +
	$initial_priority;

    $new_priority = $final_priority if ($new_priority > $final_priority);

    if ($new_priority != $priority) {
	$self->{prio} = $new_priority;
	return 1;
    }
    return 0;
}

sub Commit {
    my $self = shift;

    my ($val, $msg) = $self->TicketObj->SetPriority($self->{prio});

    unless ($val) {
	$RT::Logger->debug($self . " $msg\n");
    }
}

1;

