From 29c296af24c09dc904f6fad51edbf3c5f2f085d3 Mon Sep 17 00:00:00 2001 From: mark Date: Sat, 1 Jan 2011 06:39:17 +0000 Subject: [PATCH] ticketing escalation, part 1, RT#8254 --- FS/FS/Conf.pm | 7 +++ FS/FS/Cron/rt_tasks.pm | 108 +++++++++++++++++++++++++++++++++++ FS/bin/freeside-daily | 4 ++ rt/FREESIDE_MODIFIED | 1 + rt/lib/RT/Action/EscalatePriority.pm | 7 ++- 5 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 FS/FS/Cron/rt_tasks.pm diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm index d3cd994be..e3fc7e33a 100644 --- a/FS/FS/Conf.pm +++ b/FS/FS/Conf.pm @@ -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, DBI:Pg:user=rt_user;password=rt_word;host=rt.example.com;dbname=rt', diff --git a/FS/FS/Cron/rt_tasks.pm b/FS/FS/Cron/rt_tasks.pm new file mode 100644 index 000000000..066aeebde --- /dev/null +++ b/FS/FS/Cron/rt_tasks.pm @@ -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; diff --git a/FS/bin/freeside-daily b/FS/bin/freeside-daily index 6a542c7cd..ee3cda63e 100755 --- a/FS/bin/freeside-daily +++ b/FS/bin/freeside-daily @@ -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 ### diff --git a/rt/FREESIDE_MODIFIED b/rt/FREESIDE_MODIFIED index 73471247a..36f7a2ec4 100644 --- a/rt/FREESIDE_MODIFIED +++ b/rt/FREESIDE_MODIFIED @@ -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 diff --git a/rt/lib/RT/Action/EscalatePriority.pm b/rt/lib/RT/Action/EscalatePriority.pm index bf9de92c2..3704ee73f 100644 --- a/rt/lib/RT/Action/EscalatePriority.pm +++ b/rt/lib/RT/Action/EscalatePriority.pm @@ -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 -- 2.11.0