9 use FS::UID qw(adminsuidsetup);
10 use FS::Record qw(qsearch);
13 use vars qw($smtpmachine);
16 $FS::alerter::_template::first = "";
17 $FS::alerter::_template::last = "";
18 $FS::alerter::_template::company = "";
19 $FS::alerter::_template::payby = "";
20 $FS::alerter::_template::expdate = "";
22 # Set the mail program and other variables
23 my $mail_program = "/usr/sbin/sendmail -t -n";
24 my $mail_sender = "billing\@mydomain.tld";
25 my $default_mail_recipient = "postmaster";
26 my $warning_time = 30 * 24 * 60 * 60;
27 my $urgent_time = 15 * 24 * 60 * 60;
28 my $panic_time = 5 * 24 * 60 * 60;
29 my $window_time = 24 * 60 * 60;
31 &untaint_argv; #what it sounds like (eww)
33 #we're at now now (and later).
36 # Get the current month
37 my ($sec,$min,$hour,$mday,$mon,$year) =
38 (localtime($_date) )[0,1,2,3,4,5];
41 # Login to the database
42 my $user = shift or die &usage;
45 # Get the needed configuration files
46 my $conf = new FS::Conf;
47 $smtpmachine = $conf->config('smtpmachine');
49 my(@customers)=qsearch('cust_main',{});
50 if (scalar(@customers) == 0)
57 open (MAIL, "|$mail_program");
59 To: $default_mail_recipient
60 From: Account Processor
61 Subject: Unnotified Billing Arrangement Expirations
68 my @alerter_template = $conf->config('alerter_template')
69 or die "cannot load config file alerter_template";
71 my $alerter = new Text::Template (TYPE => 'ARRAY', SOURCE => [ map "$_\n", @alerter_template ])
72 or die "can't create new Text::Template object: Text::Template::ERROR";
73 $alerter->compile() or die "can't compile template: Text::Template::ERROR";
75 # Now I can start looping
76 foreach my $customer (@customers)
78 my $custnum = $customer->getfield('custnum');
79 my $first = $customer->getfield('first');
80 my $last = $customer->getfield('last');
81 my $company = $customer->getfield('company');
82 my $payby = $customer->getfield('payby');
83 my $payinfo = $customer->getfield('payinfo');
84 my $paydate = $customer->getfield('paydate');
85 my $daytime = $customer->getfield('daytime');
86 my $night = $customer->getfield('night');
88 my ($payyear,$paymonth,$payday) = split (/-/,$paydate);
90 my $expire_time = timelocal(0,0,0,$payday,--$paymonth,$payyear);
92 #credit cards expire at the end of the month/year of their exp date
93 if ($payby eq 'CARD') {
94 ($paymonth < 11) ? $paymonth++ : ($paymonth=0, $payyear++);
95 $expire_time = timelocal(0,0,0,$payday,$paymonth,$payyear);
99 if (($expire_time < $_date + $warning_time &&
100 $expire_time > $_date + $warning_time - $window_time) ||
101 ($expire_time < $_date + $urgent_time &&
102 $expire_time > $_date + $urgent_time - $window_time) ||
103 ($expire_time < $_date + $panic_time &&
104 $expire_time > $_date + $panic_time - $window_time)) {
108 my @packages = $customer->ncancelled_pkgs;
109 if (scalar(@packages) != 0) {
110 my @invoicing_list = $customer->invoicing_list;
111 if ( grep { $_ ne 'POST' } @invoicing_list ) {
112 $ENV{SMTPHOSTS} = $smtpmachine;
113 $ENV{MAILADDRESS} = $mail_sender;
114 my $header = new Mail::Header ( [
115 "From: $mail_sender",
116 "To: ". join(', ', grep { $_ ne 'POST' } @invoicing_list ),
117 "Sender: $mail_sender",
118 "Reply-To: $mail_sender",
119 "Date: ". time2str("%a, %d %b %Y %X %z", time),
120 "Subject: Billing Arrangement Expiration",
122 $FS::alerter::_template::first = $first;
123 $FS::alerter::_template::last = $last;
124 $FS::alerter::_template::company = $company;
125 if ($payby eq 'CARD') {
126 $FS::alerter::_template::payby = "credit card (" .
127 substr($payinfo, 0, 2) . "xxxxxxxxxx" .
128 substr($payinfo, -4) . ")";
129 }elsif ($payby eq 'COMP') {
130 $FS::alerter::_template::payby = "complimentary account";
132 $FS::alerter::_template::payby = "current method";
134 $FS::alerter::_template::expdate = $expire_time;
136 my $message = new Mail::Internet (
138 'Body' => [ $alerter->fill_in( PACKAGE => 'FS::alerter::_template' ) ],
140 $message->smtpsend or die "Can't send invoice email!: $!"; #die? warn?
142 } elsif ( ! @invoicing_list || grep { $_ eq 'POST' } @invoicing_list ) {
143 printf(MAIL qq{%5d %-32.32s %4s %10s %12s %12s\n},
145 $first . " " . $last . " " . $company,
155 # Now I need to close EMAIL
156 close MAIL || die "Could not close printer: $default_mail_recipient\n";
161 foreach $_ ( $[ .. $#ARGV ) { #untaint @ARGV
162 $ARGV[$_] =~ /^([\w\-\/]*)$/ || die "Illegal argument \"$ARGV[$_]\"";
168 die "Usage:\n\n freeside-expiration-alerter user\n";
173 freeside-expiration-alerter - Emails notifications of credit card expirations.
177 freeside-expiration-alerter user
181 Emails customers notice that their credit card or other billing arrangement
182 is about to expire. Usually run as a cron job.
184 user: From the mapsecrets file - see config.html from the base documentation
188 $Id: freeside-expiration-alerter,v 1.1 2002-03-06 22:44:13 jeff Exp $
192 Yes..... Use at your own risk. No guarantees or warrantees of any
193 kind apply to this program. Parts of this program are hacked from
194 other GNU licensed software created mainly by Ivan Kohler.
196 This is released under the GNU Public License. See www.gnu.org
197 for more information regarding this license.
201 L<FS::cust_main>, config.html from the base documentation
205 Jeff Finucane <jeff@cmh.net>