0603e6bc43774f4ebe73945b3dd054634b99d738
[freeside.git] / FS / FS / Cron / notify.pm
1 package FS::Cron::notify;
2
3 use strict;
4 use vars qw( @ISA @EXPORT_OK $DEBUG );
5 use Exporter;
6 use FS::UID qw( dbh );
7 use FS::Record qw(qsearch);
8 use FS::cust_main;
9 use FS::cust_pkg;
10
11 @ISA = qw( Exporter );
12 @EXPORT_OK = qw ( notify_flat_delay );
13 $DEBUG = 0;
14
15 sub notify_flat_delay {
16
17   my %opt = @_;
18
19   my $oldAutoCommit = $FS::UID::AutoCommit;
20   $DEBUG = 1 if $opt{'v'};
21   
22   #we're at now now (and later).
23   my($time) = $^T;
24
25   # select * from cust_pkg where
26   my $where_pkg = <<"END";
27     where ( cancel is null or cancel = 0 )
28       and ( bill > 0 )
29       and
30       0 < ( select count(*) from part_pkg
31               where cust_pkg.pkgpart = part_pkg.pkgpart
32                 and part_pkg.plan = 'flat_delayed'
33                 and 0 < ( select count(*) from part_pkg_option
34                             where part_pkg.pkgpart = part_pkg_option.pkgpart
35                               and part_pkg_option.optionname = 'recur_notify'
36                               and part_pkg_option.optionvalue > 0
37                               and 0 <= $time
38                                 + cast(part_pkg_option.optionvalue as integer)
39                                   * 86400
40                                 - cust_pkg.bill
41                               and ( cust_pkg.expire is null
42                                 or  cust_pkg.expire > $time
43                                   + cast(part_pkg_option.optionvalue as integer)
44                                     * 86400
45 END
46
47 #/*                            and ( cust_pkg.adjourn is null
48 #                                or  cust_pkg.adjourn > $time
49 #-- Should notify suspended ones  + cast(part_pkg_option.optionvalue as integer)
50 #                                    * 86400
51 #*/
52
53   $where_pkg .= <<"END";
54                                   )
55                         )
56           )
57       and
58       0 = ( select count(*) from cust_pkg_option
59               where cust_pkg.pkgnum = cust_pkg_option.pkgnum
60                 and cust_pkg_option.optionname = 'impending_recur_notification_sent'
61                 and cust_pkg_option.optionvalue = 1
62           )
63 END
64   
65   if ($opt{a}) {
66     $where_pkg .= <<END;
67       and 0 < ( select count(*) from cust_main
68                   where cust_pkg.custnum = cust_main.custnum
69                     and cust_main.agentnum = $opt{a}
70               )
71 END
72   }
73   
74   my @cust_pkg;
75   if ( @ARGV ) {
76     $where_pkg .= "and ( " . join( "OR ", map { "custnum = $_" } @ARGV) . " )";
77   } 
78
79   my $orderby = "order by custnum, bill";
80
81   my $extra_sql = "$where_pkg $orderby";
82
83   @cust_pkg = qsearch('cust_pkg', {}, '', $extra_sql );
84   
85   my @packages = ();
86   my @recurdates = ();
87   my @cust_pkgs = ();
88   while ( scalar(@cust_pkg) ) {
89     my $cust_main = $cust_pkg[0]->cust_main;
90     my $custnum = $cust_pkg[0]->custnum;
91     warn "working on $custnum" if $DEBUG;
92     while (scalar(@cust_pkg)){
93       last if ($cust_pkg[0]->custnum != $custnum);
94       warn "storing information on " . $cust_pkg[0]->pkgnum if $DEBUG;
95       push @packages, $cust_pkg[0]->part_pkg->pkg;
96       push @recurdates, $cust_pkg[0]->bill;
97       push @cust_pkgs, $cust_pkg[0];
98       shift @cust_pkg;
99     }
100     my $error = 
101       $cust_main->notify( 'impending_recur_template',
102                           'extra_fields' => { 'packages'   => \@packages,
103                                               'recurdates' => \@recurdates,
104                                               'package'    => $packages[0],
105                                               'recurdate'  => $recurdates[0],
106                                             },
107                         );
108     warn "Error notifying, custnum ". $cust_main->custnum. ": $error" if $error;
109
110     unless ($error) { 
111       local $SIG{HUP} = 'IGNORE';
112       local $SIG{INT} = 'IGNORE';
113       local $SIG{QUIT} = 'IGNORE';
114       local $SIG{TERM} = 'IGNORE';
115       local $SIG{TSTP} = 'IGNORE';
116
117       my $oldAutoCommit = $FS::UID::AutoCommit;
118       local $FS::UID::AutoCommit = 0;
119       my $dbh = dbh;
120
121       for (@cust_pkgs) {
122         my %options = ($_->options,  'impending_recur_notification_sent' => 1 );
123         $error = $_->replace( $_, options => \%options );
124         if ($error){
125           $dbh->rollback or die $dbh->errstr if $oldAutoCommit;
126           die "Error updating package options for customer". $cust_main->custnum.
127                ": $error" if $error;
128         }
129       }
130
131       $dbh->commit or die $dbh->errstr if $oldAutoCommit;
132
133     }
134
135     @packages = ();
136     @recurdates = ();
137     @cust_pkgs = ();
138   
139   }
140
141   dbh->commit or die dbh->errstr if $oldAutoCommit;
142
143 }
144
145 1;