clean up old RT sessions
[freeside.git] / FS / FS / Cron / rt_tasks.pm
1 package FS::Cron::rt_tasks;
2
3 use strict;
4 use vars qw( @ISA @EXPORT_OK $DEBUG $conf );
5 use Exporter;
6 use FS::UID qw( dbh driver_name );
7 use FS::Record qw(qsearch qsearchs);
8 use FS::TicketSystem;
9 use FS::Conf;
10
11 use Date::Parse qw(str2time);
12
13 @ISA = qw( Exporter );
14 @EXPORT_OK = qw ( rt_daily );
15 $DEBUG = 0;
16
17 FS::UID->install_callback( sub {
18   eval "use FS::Conf;";
19   die $@ if $@;
20   $conf = FS::Conf->new;
21 });
22
23
24 my %void = ();
25
26 sub rt_daily {
27   my %opt = @_;
28   my @custnums = @ARGV; # ick
29
30   # RT_External installations should have their own cron scripts for this
31   my $system = $FS::TicketSystem::system;
32   return if !defined($system) || $system ne 'RT_Internal';
33
34   system('/opt/rt3/sbin/rt-clean-sessions --older 1M --skip-user &');
35
36   system('/opt/rt3/sbin/rt-fulltext-indexer --quiet --limit 5400 &');
37
38   # if -d or -y is in use, bail out.  There's no reliable way to tell RT 
39   # to use an alternate system time.
40   if ( $opt{'d'} or $opt{'y'} ) {
41     warn "Forced date options in use - RT daily tasks skipped.\n";
42     return;
43   }
44
45   FS::TicketSystem->init;
46   my $session = FS::TicketSystem->session();
47   my $CurrentUser = $session->{'CurrentUser'}
48     or die "Failed to create RT session";
49
50   $DEBUG = 1 if $opt{'v'};
51   RT::Config->Set( LogToScreen => 'debug' ) if $DEBUG;
52  
53   # load some modules that aren't handled in FS::TicketSystem 
54   foreach (qw(
55     Search::ActiveTicketsInQueue
56     Action::EscalatePriority
57     Action::EscalateQueue
58     Action::ScheduledResolve
59     )) {
60     eval "use RT::$_";
61     die $@ if $@;
62   }
63
64   # adapted from rt-crontool
65
66   # to make some actions work without complaining
67   %void = map { $_ => "RT::$_"->new($CurrentUser) }
68     (qw(Scrip ScripAction));
69
70   # compile actions to be run
71   my (@actions, @active_tickets);
72   my $queues = RT::Queues->new($CurrentUser);
73   $queues->UnLimit;
74   while (my $queue = $queues->Next) {
75     warn "Queue '".$queue->Name."'\n" if $DEBUG;
76     my %opt = @_;
77     my $tickets = RT::Tickets->new($CurrentUser);
78     my $search = RT::Search::ActiveTicketsInQueue->new(
79       TicketsObj  => $tickets,
80       Argument    => $queue->Id,
81       CurrentUser => $CurrentUser,
82     );
83     $search->Prepare;
84     foreach my $custnum ( @custnums ) {
85       die "invalid custnum passed to rt_daily: $custnum"
86         if !$custnum =~ /^\d+$/;
87       $tickets->LimitMemberOf(
88         "freeside://freeside/cust_main/$custnum",
89         ENTRYAGGREGATOR => 'OR',
90         SUBCLAUSE => 'custnum'
91       );
92     }
93     while (my $ticket = $tickets->Next) {
94       warn 'Ticket #'.$ticket->Id()."\n" if $DEBUG;
95       my @a = task_actions($ticket);
96       push @actions, @a;
97       push @active_tickets, $ticket if @a; # avoid garbage collection
98     }
99   }
100
101   # and then commit them all
102   foreach (grep {$_} @actions) {
103     my ($val, $msg) = $_->Commit;
104     if ( $DEBUG ) {
105       if ($val) {
106         warn "Action committed: ".ref($_)." #".$_->TicketObj->Id."\n";
107       }
108       else {
109         warn "Action returned $msg: #".$_->TicketObj->Id."\n";
110       }
111     }
112   }
113   return;
114 }
115
116 sub task_actions {
117   my $ticket = shift;
118   (
119     ### escalation ###
120     $conf->exists('ticket_system-escalation') ? (
121       action($ticket, 'EscalatePriority', "CurrentTime: $^T"),
122       action($ticket, 'EscalateQueue')
123     ) : (),
124
125     ### scheduled resolve ###
126     action($ticket, 'ScheduledResolve'),
127   );
128 }
129
130 sub action {
131   my $ticket = shift;
132   my $CurrentUser = $ticket->CurrentUser;
133
134   my $action = shift;
135   my $argument = shift;
136
137   $action = "RT::Action::$action";
138   my $action_obj = $action->new(
139     TicketObj     => $ticket,
140     Argument      => $argument,
141     Scrip         => $void{'Scrip'},
142     ScripAction   => $void{'ScripAction'},
143     CurrentUser   => $CurrentUser,
144   );
145   if ( $action_obj->Prepare ) {
146     warn "Action prepared: $action\n" if $DEBUG;
147     return $action_obj;
148   }
149   else {
150     return;
151   }
152 }
153
154 1;