ticketing escalation, part 1, RT#8254
authormark <mark>
Sat, 1 Jan 2011 06:39:17 +0000 (06:39 +0000)
committermark <mark>
Sat, 1 Jan 2011 06:39:17 +0000 (06:39 +0000)
FS/FS/Conf.pm
FS/FS/Cron/rt_tasks.pm [new file with mode: 0644]
FS/bin/freeside-daily
rt/FREESIDE_MODIFIED
rt/lib/RT/Action/EscalatePriority.pm

index d3cd994..e3fc7e3 100644 (file)
@@ -2552,6 +2552,13 @@ and customer address. Include units.',
   },
 
   {
+    'key'         => 'ticket_system-escalation',
+    'section'     => '',
+    'description' => 'Enable priority escalation of tickets as part of daily batch processing.',
+    'type'        => 'checkbox',
+  },
+
+  {
     'key'         => 'ticket_system-rt_external_datasrc',
     'section'     => '',
     'description' => 'With external RT integration, the DBI data source for the external RT installation, for example, <code>DBI:Pg:user=rt_user;password=rt_word;host=rt.example.com;dbname=rt</code>',
diff --git a/FS/FS/Cron/rt_tasks.pm b/FS/FS/Cron/rt_tasks.pm
new file mode 100644 (file)
index 0000000..066aeeb
--- /dev/null
@@ -0,0 +1,108 @@
+package FS::Cron::rt_tasks;
+
+use strict;
+use vars qw( @ISA @EXPORT_OK $DEBUG );
+use Exporter;
+use FS::UID qw( dbh driver_name );
+use FS::Record qw(qsearch qsearchs);
+use FS::TicketSystem;
+use FS::Conf;
+
+use Date::Parse qw(str2time);
+
+@ISA = qw( Exporter );
+@EXPORT_OK = qw ( rt_escalate );
+$DEBUG = 0;
+
+my %void = ();
+
+sub rt_escalate {
+  my %opt = @_;
+  # RT_External installations should have their own cron scripts for this
+  my $system = $FS::TicketSystem::system;
+  return if $system ne 'RT_Internal';
+
+  my $conf = new FS::Conf;
+  return if !$conf->exists('ticket_system-escalation');
+
+  FS::TicketSystem->init;
+  $DEBUG = 1 if $opt{'v'};
+  RT::Config->Set( LogToScreen => 'debug' ) if $DEBUG;
+  
+  #we're at now now (and later).
+  my $time = $opt{'d'} ? str2time($opt{'d'}) : $^T;
+  $time += $opt{'y'} * 86400 if $opt{'y'};
+  my $error = '';
+
+  my $session = FS::TicketSystem->session();
+  my $CurrentUser = $session->{'CurrentUser'}
+    or die "Failed to create RT session";
+  # load some modules that aren't handled in FS::TicketSystem 
+  foreach (qw(
+    Search::ActiveTicketsInQueue 
+    Action::EscalatePriority
+    )) {
+    eval "use RT::$_";
+    die $@ if $@;
+  }
+
+  # adapted from rt-crontool
+  # Mechanics:
+  # We're using EscalatePriority, so search in all queues that have a 
+  # priority range defined. Select all active tickets in those queues and
+  # LinearEscalate them.
+
+  # to make some actions work without complaining
+  %void = map { $_ => "RT::$_"->new($CurrentUser) }
+    (qw(Scrip ScripAction));
+
+  # Most of this stuff is common to any condition -> action processing 
+  # we might want to do, but escalation is the only one we do now.
+  my $queues = RT::Queues->new($CurrentUser);
+  $queues->UnLimit;
+  while (my $queue = $queues->Next) {
+    if ( $queue->InitialPriority == $queue->FinalPriority ) {
+      warn "Queue '".$queue->Name."' (skipped)\n" if $DEBUG;
+      next;
+    }
+    warn "Queue '".$queue->Name."'\n" if $DEBUG;
+    my $tickets = RT::Tickets->new($CurrentUser);
+    my $search = RT::Search::ActiveTicketsInQueue->new(
+      TicketsObj  => $tickets,
+      Argument    => $queue->Name,
+      CurrentUser => $CurrentUser,
+    );
+    $search->Prepare;
+    while (my $ticket = $tickets->Next) {
+      warn 'Ticket #'.$ticket->Id()."\n" if $DEBUG;
+      # We don't need transaction stuff from rt-crontool here
+      action($ticket, 'EscalatePriority', "CurrentTime:$time");
+    }
+  }
+  return;
+}
+
+sub action {
+  my $ticket = shift;
+  my $CurrentUser = $ticket->CurrentUser;
+
+  my $action = shift;
+  my $argument = shift;
+
+  $action = "RT::Action::$action";
+  my $action_obj = $action->new(
+    TicketObj     => $ticket,
+    Argument      => $argument,
+    Scrip         => $void{'Scrip'},
+    ScripAction   => $void{'ScripAction'},
+    CurrentUser   => $CurrentUser,
+  );
+  return unless $action_obj->Prepare;
+  warn "Action prepared: $action\n" if $DEBUG;
+  $action_obj->Commit;
+  warn "Action committed: $action\n" if $DEBUG;
+  return;
+}
+
+1;
index 6a542c7..ee3cda6 100755 (executable)
@@ -50,6 +50,10 @@ if ( $opt{u} ) {
 use FS::Cron::backup qw(backup_scp);
 backup_scp();
 
+#same
+use FS::Cron::rt_tasks qw(rt_escalate);
+rt_escalate(%opt);
+
 ###
 # subroutines
 ###
index 7347124..36f7a2e 100644 (file)
@@ -15,6 +15,7 @@ lib/RT/Action.pm #create ticket on custom field change
 lib/RT/Condition.pm #create ticket on custom field change
 lib/RT/Scrip_Overlay.pm #create ticket on custom field change
 lib/RT/Action/CreateTickets.pm #create ticket on custom field change
+lib/RT/Action/EscalatePriority.pm #ticket escalation
 lib/RT/Condition/CustomFieldChange.pm #create ticket on custom field change
 lib/RT/Interface/Web_Vendor.pm
  lib/RT/Interface/Web/Handler.pm #freeside comp_root for dashboard emails
index bf9de92..3704ee7 100644 (file)
@@ -121,7 +121,12 @@ sub Prepare  {
 
     # we've got a due date. now there are other things we should do
     else { 
-       my $diff_in_seconds = $due->Diff(time());    
+        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