diff options
author | mark <mark> | 2011-08-23 21:45:51 +0000 |
---|---|---|
committer | mark <mark> | 2011-08-23 21:45:51 +0000 |
commit | 4c8c18409f82d56320a80f6c94f275fa15486897 (patch) | |
tree | deeb2cb64572fb1cd00cb55be48eaa68a69d9984 /FS | |
parent | 006b2392be94f9670eddf3d01ba89c00f9c16c05 (diff) |
RT future ticket resolve, #13853
Diffstat (limited to 'FS')
-rw-r--r-- | FS/FS/Cron/rt_tasks.pm | 86 | ||||
-rw-r--r-- | FS/FS/TicketSystem.pm | 49 | ||||
-rw-r--r-- | FS/FS/Upgrade.pm | 2 | ||||
-rwxr-xr-x | FS/bin/freeside-daily | 4 | ||||
-rwxr-xr-x | FS/bin/freeside-upgrade | 15 |
5 files changed, 107 insertions, 49 deletions
diff --git a/FS/FS/Cron/rt_tasks.pm b/FS/FS/Cron/rt_tasks.pm index 26e305d59..6658b4781 100644 --- a/FS/FS/Cron/rt_tasks.pm +++ b/FS/FS/Cron/rt_tasks.pm @@ -1,7 +1,7 @@ package FS::Cron::rt_tasks; use strict; -use vars qw( @ISA @EXPORT_OK $DEBUG ); +use vars qw( @ISA @EXPORT_OK $DEBUG $conf ); use Exporter; use FS::UID qw( dbh driver_name ); use FS::Record qw(qsearch qsearchs); @@ -11,83 +11,91 @@ use FS::Conf; use Date::Parse qw(str2time); @ISA = qw( Exporter ); -@EXPORT_OK = qw ( rt_escalate ); +@EXPORT_OK = qw ( rt_daily ); $DEBUG = 0; +FS::UID->install_callback( sub { + eval "use FS::Conf;"; + die $@ if $@; + $conf = FS::Conf->new; +}); + + my %void = (); -sub rt_escalate { +sub rt_daily { my %opt = @_; + my @custnums = @ARGV; # ick + # 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 = ''; + + # if -d or -y is in use, bail out. There's no reliable way to tell RT + # to use an alternate system time. + if ( $opt{'d'} or $opt{'y'} ) { + warn "Forced date options in use - RT daily tasks skipped.\n"; + return; + } 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 + Search::ActiveTicketsInQueue Action::EscalatePriority Action::EscalateQueue + Action::ScheduledResolve )) { 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 - # EscalatePriority, then EscalateQueue 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. + # compile actions to be run + my (@actions, @active_tickets); my $queues = RT::Queues->new($CurrentUser); $queues->UnLimit; - my @actions = (); - my @active_tickets = (); 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 $CurrentUser = $queue->CurrentUser; + my %opt = @_; my $tickets = RT::Tickets->new($CurrentUser); my $search = RT::Search::ActiveTicketsInQueue->new( TicketsObj => $tickets, - Argument => $queue->Name, + Argument => $queue->Id, CurrentUser => $CurrentUser, ); $search->Prepare; + foreach my $custnum ( @custnums ) { + die "invalid custnum passed to rt_daily: $custnum" + if !$custnum =~ /^\d+$/; + $tickets->LimitMemberOf( + "freeside://freeside/cust_main/$custnum", + ENTRYAGGREGATOR => 'OR', + SUBCLAUSE => 'custnum' + ); + } while (my $ticket = $tickets->Next) { warn 'Ticket #'.$ticket->Id()."\n" if $DEBUG; - my @a = ( - action($ticket, 'EscalatePriority', "CurrentTime:$time"), - action($ticket, 'EscalateQueue') - ); - next if !@a; + my @a = task_actions($ticket); push @actions, @a; - push @active_tickets, $ticket; # avoid RT's overzealous garbage collector + push @active_tickets, $ticket if @a; # avoid garbage collection } } + + # and then commit them all foreach (grep {$_} @actions) { my ($val, $msg) = $_->Commit; if ( $DEBUG ) { @@ -102,6 +110,20 @@ sub rt_escalate { return; } +sub task_actions { + my $ticket = shift; + ( + ### escalation ### + $conf->exists('ticket_system-escalation') ? ( + action($ticket, 'EscalatePriority', "CurrentTime: $^T"), + action($ticket, 'EscalateQueue') + ) : (), + + ### scheduled resolve ### + action($ticket, 'ScheduledResolve'), + ); +} + sub action { my $ticket = shift; my $CurrentUser = $ticket->CurrentUser; diff --git a/FS/FS/TicketSystem.pm b/FS/FS/TicketSystem.pm index 63ab865c4..169f0dc4d 100644 --- a/FS/FS/TicketSystem.pm +++ b/FS/FS/TicketSystem.pm @@ -4,6 +4,7 @@ use strict; use vars qw( $conf $system $AUTOLOAD ); use FS::Conf; use FS::UID qw( dbh driver_name ); +use FS::Record qw( dbdef ); FS::UID->install_callback( sub { $conf = new FS::Conf; @@ -27,6 +28,54 @@ sub AUTOLOAD { $self->$sub(@_); } +# Our schema changes +my %columns = ( + Tickets => { + WillResolve => { type => 'timestamp', null => 1, default => '', }, + }, + CustomFields => { + Required => { type => 'integer', default => 0, null => 0 }, + }, +); + +sub _upgrade_schema { + my $system = FS::Conf->new->config('ticket_system'); + return if !defined($system) || $system ne 'RT_Internal'; + my ($class, %opts) = @_; + + my $dbh = dbh; + my @sql; + my $case = driver_name eq 'mysql' ? sub {@_} : sub {map lc, @_}; + foreach my $tablename (keys %columns) { + my $table = dbdef->table(&$case($tablename)); + if ( !$table ) { + warn + "$tablename table does not exist. Your RT installation is incomplete.\n"; + next; + } + foreach my $colname (keys %{ $columns{$tablename} }) { + if ( !$table->column(&$case($colname)) ) { + my $col = new DBIx::DBSchema::Column { + table_obj => $table, + name => &$case($colname), + %{ $columns{$tablename}->{$colname} } + }; + $col->table_obj($table); + push @sql, $col->sql_add_column($dbh); + } + } #foreach $colname + } #foreach $tablename + + return if !@sql; + warn "Upgrading RT schema:\n"; + foreach my $statement (@sql) { + warn "$statement\n"; + $dbh->do( $statement ) + or die "Error: ". $dbh->errstr. "\n executing: $statement"; + } + return; +} + sub _upgrade_data { return if !defined($system) || $system ne 'RT_Internal'; my ($class, %opts) = @_; diff --git a/FS/FS/Upgrade.pm b/FS/FS/Upgrade.pm index 40d347327..03d24f7f6 100644 --- a/FS/FS/Upgrade.pm +++ b/FS/FS/Upgrade.pm @@ -303,6 +303,8 @@ sub upgrade_schema_data { #fix classnum character(1) 'cust_bill_pkg_detail' => [], + #add necessary columns to RT schema + 'TicketSystem' => [], ; diff --git a/FS/bin/freeside-daily b/FS/bin/freeside-daily index a7c38d557..2beb096ab 100755 --- a/FS/bin/freeside-daily +++ b/FS/bin/freeside-daily @@ -62,8 +62,8 @@ use FS::Cron::backup qw(backup); backup(); #same -use FS::Cron::rt_tasks qw(rt_escalate); -rt_escalate(%opt); +use FS::Cron::rt_tasks qw(rt_daily); +rt_daily(%opt); my $deldir = "$FS::UID::cache_dir/cache.$FS::UID::datasrc/"; unlink <${deldir}.invoice*>; diff --git a/FS/bin/freeside-upgrade b/FS/bin/freeside-upgrade index 6f4e43983..b08a8401f 100755 --- a/FS/bin/freeside-upgrade +++ b/FS/bin/freeside-upgrade @@ -84,21 +84,6 @@ if ( dbdef->table('areacode') and } } -# RT required field flag -# for consistency with RT schema: mysql is in CamelCase, -# pg is in lowercase, and they use different data types. -my ($t, $creq, $cdis) = - map { driver_name =~ /^mysql/i ? $_ : lc($_) } - ('CustomFields','Required','Disabled'); - -if ( dbdef->table($t) && - ! dbdef->table($t)->column($creq) ) { - push @bugfix, - "ALTER TABLE $t ADD COLUMN $creq ". - dbdef->table($t)->column($cdis)->type . - ' NOT NULL DEFAULT 0'; -} - if ( $DRY_RUN ) { print join(";\n", @bugfix ). ";\n"; |