1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
|
package FS::Cron::rt_tasks;
use strict;
use vars qw( @ISA @EXPORT_OK $DEBUG $conf );
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_daily );
$DEBUG = 0;
FS::UID->install_callback( sub {
eval "use FS::Conf;";
die $@ if $@;
$conf = FS::Conf->new;
});
my %void = ();
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';
FS::TicketSystem->init;
$DEBUG = 1 if $opt{'v'};
RT::Config->Set( LogToScreen => 'debug' ) if $DEBUG;
# 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
Action::EscalatePriority
Action::EscalateQueue
Action::ScheduledResolve
)) {
eval "use RT::$_";
die $@ if $@;
}
# adapted from rt-crontool
# to make some actions work without complaining
%void = map { $_ => "RT::$_"->new($CurrentUser) }
(qw(Scrip ScripAction));
# compile actions to be run
my (@actions, @active_tickets);
my $queues = RT::Queues->new($CurrentUser);
$queues->UnLimit;
while (my $queue = $queues->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->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 = task_actions($ticket);
push @actions, @a;
push @active_tickets, $ticket if @a; # avoid garbage collection
}
}
# and then commit them all
foreach (grep {$_} @actions) {
my ($val, $msg) = $_->Commit;
if ( $DEBUG ) {
if ($val) {
warn "Action committed: ".ref($_)." #".$_->TicketObj->Id."\n";
}
else {
warn "Action returned $msg: #".$_->TicketObj->Id."\n";
}
}
}
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;
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,
);
if ( $action_obj->Prepare ) {
warn "Action prepared: $action\n" if $DEBUG;
return $action_obj;
}
else {
return;
}
}
1;
|