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