# BEGIN BPS TAGGED BLOCK {{{
-#
+#
# COPYRIGHT:
-#
-# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC
-# <jesse@bestpractical.com>
-#
+#
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
+# <sales@bestpractical.com>
+#
# (Except where explicitly superseded by other copyright notices)
-#
-#
+#
+#
# LICENSE:
-#
+#
# This work is made available to you under the terms of Version 2 of
# the GNU General Public License. A copy of that license should have
# been provided with this software, but in any event can be snarfed
# from www.gnu.org.
-#
+#
# This work is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
-#
+#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-#
-#
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+#
+#
# CONTRIBUTION SUBMISSION POLICY:
-#
+#
# (The following paragraph is not intended to limit the rights granted
# to you to modify and distribute this software under the terms of
# the GNU General Public License and is only of importance to you if
# you choose to contribute your changes and enhancements to the
# community by submitting them to Best Practical Solutions, LLC.)
-#
+#
# By intentionally submitting any modifications, corrections or
# derivatives to this work, or any other work intended for use with
# Request Tracker, to Best Practical Solutions, LLC, you confirm that
# royalty-free, perpetual, license to use, copy, create derivative
# works based on those contributions, and sublicense and distribute
# those contributions and any derivatives thereof.
-#
+#
# END BPS TAGGED BLOCK }}}
=head1 NAME
In this way, priority is either increased or decreased toward the final priority
as the ticket heads toward its due date.
+Alternately, if you don't set a due date, the Priority will be incremented by 1
+until it reaches the Final Priority. If a ticket without a due date has a Priority
+greater than Final Priority, it will be decremented by 1.
+
+=head2 CONFIGURATION
+
+EsclatePriority's behavior can be controlled by two options:
+
+=over 4
+
+=item RecordTransaction
+
+If true (the default), the action casuses a transaction on the ticket
+when it is escalated. If false, the action updates the priority without
+running scrips or recording a transaction.
+
+=item UpdateLastUpdated
+
+If true (the default), the action updates the LastUpdated field when the
+ticket is escalated. You cannot set C<UpdateLastUpdated> to false unless
+C<RecordTransaction> is also false.
+
+=back
+
+To use these with C<rt-crontool>, specify them with C<--action-arg>:
+
+ --action-arg "RecordTransaction: 0, UpdateLastUpdated: 0"
=cut
package RT::Action::EscalatePriority;
-require RT::Action::Generic;
+use base 'RT::Action';
use strict;
-use vars qw/@ISA/;
-@ISA=qw(RT::Action::Generic);
+use warnings;
#Do what we need to do and send it out.
#What does this type of Action does
-# {{{ sub Describe
sub Describe {
my $self = shift;
return (ref $self . " will move a ticket's priority toward its final priority.");
}
-# }}}
-
-# {{{ sub Prepare
+
sub Prepare {
my $self = shift;
-
+
if ($self->TicketObj->Priority() == $self->TicketObj->FinalPriority()) {
- # no update necessary.
- return 0;
+ # no update necessary.
+ return 0;
}
-
+
#compute the number of days until the ticket is due
my $due = $self->TicketObj->DueObj();
-
+
# If we don't have a due date, adjust the priority by one
# until we hit the final priority
- if ($due->Unix() < 1) {
- if ( $self->TicketObj->Priority > $self->TicketObj->FinalPriority ){
- $self->{'prio'} = ($self->TicketObj->Priority - 1);
- return 1;
- }
- elsif ( $self->TicketObj->Priority < $self->TicketObj->FinalPriority ){
- $self->{'prio'} = ($self->TicketObj->Priority + 1);
- return 1;
- }
- # otherwise the priority is at the final priority. we don't need to
- # Continue
- else {
- return 0;
- }
+ if (not $due->IsSet) {
+ if ( $self->TicketObj->Priority > $self->TicketObj->FinalPriority ){
+ $self->{'prio'} = ($self->TicketObj->Priority - 1);
+ return 1;
+ }
+ elsif ( $self->TicketObj->Priority < $self->TicketObj->FinalPriority ){
+ $self->{'prio'} = ($self->TicketObj->Priority + 1);
+ return 1;
+ }
+ # otherwise the priority is at the final priority. we don't need to
+ # Continue
+ else {
+ return 0;
+ }
}
# we've got a due date. now there are other things we should do
- else {
- my $diff_in_seconds = $due->Diff(time());
- my $diff_in_days = int( $diff_in_seconds / 86400);
-
- #if we haven't hit the due date yet
- if ($diff_in_days > 0 ) {
-
- # compute the difference between the current priority and the
- # final priority
-
- my $prio_delta =
- $self->TicketObj->FinalPriority() - $self->TicketObj->Priority;
-
- my $inc_priority_by = int( $prio_delta / $diff_in_days );
-
- #set the ticket's priority to that amount
- $self->{'prio'} = $self->TicketObj->Priority + $inc_priority_by;
-
- }
- #if $days is less than 1, set priority to final_priority
- else {
- $self->{'prio'} = $self->TicketObj->FinalPriority();
- }
+ else {
+ my $arg = $self->Argument || '';
+ my $now = time();
+ if ( $arg =~ /CurrentTime:\s*(\d+)/i ) {
+ $now = $1;
+ }
+ my $diff_in_seconds = $due->Diff($now);
+ my $diff_in_days = int( $diff_in_seconds / 86400);
+
+ #if we haven't hit the due date yet
+ if ($diff_in_days > 0 ) {
+
+ # compute the difference between the current priority and the
+ # final priority
+
+ my $prio_delta =
+ $self->TicketObj->FinalPriority() - $self->TicketObj->Priority;
+
+ my $inc_priority_by = int( $prio_delta / $diff_in_days );
+
+ #set the ticket's priority to that amount
+ $self->{'prio'} = $self->TicketObj->Priority + $inc_priority_by;
+
+ }
+ #if $days is less than 1, set priority to final_priority
+ else {
+ $self->{'prio'} = $self->TicketObj->FinalPriority();
+ }
}
return 1;
}
-# }}}
sub Commit {
my $self = shift;
- my ($val, $msg) = $self->TicketObj->SetPriority($self->{'prio'});
+ my $new_value = $self->{'prio'};
+ return 1 unless defined $new_value;
+
+ my $ticket = $self->TicketObj;
+ return 1 if $ticket->Priority == $new_value;
+
+ # Overide defaults from argument
+ my($record, $update) = (1, 1);
+ {
+ my $arg = $self->Argument || '';
+ if ( $arg =~ /RecordTransaction:\s*(\d+)/i ) {
+ $record = $1;
+ $RT::Logger->debug("Overrode RecordTransaction: $record");
+ }
+ if ( $arg =~ /UpdateLastUpdated:\s*(\d+)/i ) {
+ $update = $1;
+ $RT::Logger->debug("Overrode UpdateLastUpdated: $update");
+ }
+ # If creating a transaction, we have to update lastupdated
+ $update = 1 if $record;
+ }
+
+ $RT::Logger->debug(
+ 'Escalating priority of ticket #'. $ticket->Id
+ .' from '. $ticket->Priority .' to '. $new_value
+ .' and'. ($record? '': ' do not') .' record a transaction'
+ .' and'. ($update? '': ' do not') .' touch last updated field'
+ );
+
+ my ($val, $msg);
+ unless ( $record ) {
+ unless ( $update ) {
+ ( $val, $msg ) = $ticket->__Set(
+ Field => 'Priority',
+ Value => $new_value,
+ );
+ } else {
+ ( $val, $msg ) = $ticket->_Set(
+ Field => 'Priority',
+ Value => $new_value,
+ RecordTransaction => 0,
+ );
+ }
+ } else {
+ ($val, $msg) = $ticket->SetPriority($new_value);
+ }
- unless ($val) {
- $RT::Logger->debug($self . " $msg\n");
- }
+ unless ($val) {
+ $RT::Logger->error( "Couldn't set new priority value: $msg");
+ return (0, $msg);
+ }
+ return 1;
}
-eval "require RT::Action::EscalatePriority_Vendor";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/Action/EscalatePriority_Vendor.pm});
-eval "require RT::Action::EscalatePriority_Local";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/Action/EscalatePriority_Local.pm});
+RT::Base->_ImportOverlays();
1;