This commit was manufactured by cvs2svn to create tag 'freeside_2_1_0'.
[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 driver_name );
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   my $integer = driver_name =~ /^mysql/ ? 'SIGNED' : 'INTEGER';
26
27   # select * from cust_pkg where
28   my $where_pkg = <<"END";
29     where ( cancel is null or cancel = 0 )
30       and ( bill > 0 )
31       and
32       0 < ( select count(*) from part_pkg
33               where cust_pkg.pkgpart = part_pkg.pkgpart
34                 and part_pkg.plan = 'flat_delayed'
35                 and 0 < ( select count(*) from part_pkg_option
36                             where part_pkg.pkgpart = part_pkg_option.pkgpart
37                               and part_pkg_option.optionname = 'recur_notify'
38                               and CAST( part_pkg_option.optionvalue AS INTEGER ) > 0
39                               and 0 <= ( $time
40                                          + CAST( part_pkg_option.optionvalue AS $integer )
41                                            * 86400
42                                          - cust_pkg.bill
43                                        )
44                               and ( cust_pkg.expire is null
45                                 or  cust_pkg.expire > ( $time
46                                                         + CAST( part_pkg_option.optionvalue AS $integer )
47                                                           * 86400
48                                                       )
49 END
50
51 #/*                            and ( cust_pkg.adjourn is null
52 #                                or  cust_pkg.adjourn > $time
53 #-- Should notify suspended ones  + cast(part_pkg_option.optionvalue as $integer)
54 #                                    * 86400
55 #*/
56
57   $where_pkg .= <<"END";
58                                   )
59                         )
60           )
61       and
62       0 = ( select count(*) from cust_pkg_option
63               where cust_pkg.pkgnum = cust_pkg_option.pkgnum
64                 and cust_pkg_option.optionname = 'impending_recur_notification_sent'
65                 and CAST( cust_pkg_option.optionvalue AS INTEGER ) = 1
66           )
67 END
68   
69   if ($opt{a}) {
70     $where_pkg .= <<END;
71       and 0 < ( select count(*) from cust_main
72                   where cust_pkg.custnum = cust_main.custnum
73                     and cust_main.agentnum = $opt{a}
74               )
75 END
76   }
77   
78   my @cust_pkg;
79   if ( @ARGV ) {
80     $where_pkg .= "and ( " . join( "OR ", map { "custnum = $_" } @ARGV) . " )";
81   } 
82
83   my $orderby = "order by custnum, bill";
84
85   my $extra_sql = "$where_pkg $orderby";
86
87   @cust_pkg = qsearch('cust_pkg', {}, '', $extra_sql );
88   
89   my @packages = ();
90   my @recurdates = ();
91   my @cust_pkgs = ();
92   while ( scalar(@cust_pkg) ) {
93     my $cust_main = $cust_pkg[0]->cust_main;
94     my $custnum = $cust_pkg[0]->custnum;
95     warn "working on $custnum" if $DEBUG;
96     while (scalar(@cust_pkg)){
97       last if ($cust_pkg[0]->custnum != $custnum);
98       warn "storing information on " . $cust_pkg[0]->pkgnum if $DEBUG;
99       push @packages, $cust_pkg[0]->part_pkg->pkg;
100       push @recurdates, $cust_pkg[0]->bill;
101       push @cust_pkgs, $cust_pkg[0];
102       shift @cust_pkg;
103     }
104     my $error = 
105       $cust_main->notify( 'impending_recur_template',
106                           'extra_fields' => { 'packages'   => \@packages,
107                                               'recurdates' => \@recurdates,
108                                               'package'    => $packages[0],
109                                               'recurdate'  => $recurdates[0],
110                                             },
111                         );
112     warn "Error notifying, custnum ". $cust_main->custnum. ": $error" if $error;
113
114     unless ($error) { 
115       local $SIG{HUP} = 'IGNORE';
116       local $SIG{INT} = 'IGNORE';
117       local $SIG{QUIT} = 'IGNORE';
118       local $SIG{TERM} = 'IGNORE';
119       local $SIG{TSTP} = 'IGNORE';
120
121       my $oldAutoCommit = $FS::UID::AutoCommit;
122       local $FS::UID::AutoCommit = 0;
123       my $dbh = dbh;
124
125       for (@cust_pkgs) {
126         my %options = ($_->options,  'impending_recur_notification_sent' => 1 );
127         $error = $_->replace( $_, options => \%options );
128         if ($error){
129           $dbh->rollback or die $dbh->errstr if $oldAutoCommit;
130           die "Error updating package options for customer". $cust_main->custnum.
131                ": $error" if $error;
132         }
133       }
134
135       $dbh->commit or die $dbh->errstr if $oldAutoCommit;
136
137     }
138
139     @packages = ();
140     @recurdates = ();
141     @cust_pkgs = ();
142   
143   }
144
145   dbh->commit or die dbh->errstr if $oldAutoCommit;
146
147 }
148
149 1;