afterthought
[freeside.git] / bin / bill
1 #!/usr/bin/perl -Tw
2
3 use strict;
4 use Fcntl qw(:flock);
5 use Date::Parse;
6 use Getopt::Std;
7 use FS::UID qw(adminsuidsetup swapuid);
8 use FS::Record qw(qsearch qsearchs);
9 use FS::cust_main;
10
11 &untaint_argv;  #what it sounds like  (eww)
12 use vars qw($opt_b $opt_c $opt_i $opt_d);
13 getopts("bcid:");       #switches
14 my $user = shift or die &usage;
15
16 adminsuidsetup $user;
17
18 #we're at now now (and later).
19 my($time)= $main::opt_d ? str2time($main::opt_d) : $^T;
20
21 # find packages w/ bill < time && cancel != '', and create corresponding
22 # customer objects
23
24 my($cust_main,%saw);
25 foreach $cust_main (
26   map {
27     if ( ( $_->getfield('bill') || 0 ) <= $time &&
28          !$saw{ $_->getfield('custnum') }++ ) {
29       qsearchs('cust_main',{'custnum'=> $_->getfield('custnum') } );
30     } else {
31       ();
32     }
33   } ( qsearch('cust_pkg', { 'cancel' => '' }),
34       qsearch('cust_pkg', { 'cancel' => 0  }),
35     )
36 ) {
37
38   # and bill them
39
40   print "Billing customer #" . $cust_main->getfield('custnum') . "\n";
41
42   my($error);
43
44   $error=$cust_main->bill('time'=>$time);
45   warn "Error billing,  customer #" . $cust_main->getfield('custnum') . 
46     ":" . $error if $error;
47
48   if ($main::opt_c) {
49     $error=$cust_main->collect('invoice_time'=>$time,
50                                'batch_card' => $main::opt_i ? 'no' : 'yes',
51                               );
52     warn "Error collecting customer #" . $cust_main->getfield('custnum') .
53       ":" . $error if $error;
54
55   #sleep 1;
56
57   }
58
59 }
60
61 # subroutines
62
63 sub untaint_argv {
64   foreach $_ ( $[ .. $#ARGV ) { #untaint @ARGV
65     $ARGV[$_] =~ /^([\w\-\/]*)$/ || die "Illegal arguement \"$ARGV[$_]\"";
66     $ARGV[$_]=$1;
67   }
68 }
69
70 sub usage {
71   die "Usage:\n\n  bill [ -c [ i ] ] [ -d 'date' ] [ -b ] user\n";
72 }
73
74 =head1 NAME
75
76 bill - Command line (crontab, script) interface to customer billing.
77
78 =head1 SYNOPSIS
79
80   bill [ -c [ i ] ] [ -d 'date' ] user
81
82 =head1 DESCRIPTION
83
84 Bills all customers.  Searches for customers who are due for billing and calls
85 the bill and collect methods of a cust_main object.  See L<FS::cust_main>.
86
87 -c: Turn on collecting (you probably want this).
88
89 -i: real-time billing (as opposed to batch billing).  only relevant
90     for credit cards.
91
92 -d: Pretent it's 'date'.  Date is in any format Date::Parse is happy with,
93     but be careful.
94
95 user: From the mapsecrets file - see config.html from the base documentation
96
97 =head1 VERSION
98
99 $Id: bill,v 1.6 1998-11-15 02:53:00 ivan Exp $
100
101 =head1 BUGS
102
103 =head1 SEE ALSO
104
105 L<FS::cust_main>, config.html from the base documentation
106
107 =head1 HISTORY
108
109 ivan@voicenet.com sep/oct 96
110
111 separated billing and collections, cleaned up code.
112 ivan@voicenet.com 96-nov-11
113
114 added -d option
115 ivan@voicenet.com 96-nov-13
116
117 added -v option and started to implement it, added 'd:' to getopts call
118   (oops!)
119 ivan@voicenet.com 97-jan-2
120
121 added more debug messages, moved some searches to fssearch.pl library (for 
122 speed)
123 rewrote "all customer" finder to know about bill dates, for speed.
124 ivan@voicenet.com 97-jan-8
125
126 thought about it a while, and removed passing of the -d option to collect...?
127 ivan@voicenet.com 97-jan-14
128
129 make all -v stuff STDERR 
130 ivan@voicenet.com 97-feb-4
131
132 added pkgnum as argument to program from /db/part_pkg, with kludge for the
133 "/bin/echo XX" 's already there.
134 ivan@voicenet.com 97-feb-23
135
136 - general cleanup
137 - customers who are suspended can still be billed for the setup fee
138 - cust_pkg record is re-read after the package setup fee program is run.
139   this way,
140   that program can modify the record (for example, to start accounts off
141   suspended)
142   (best to think four or five times before modifying anything else!)
143 ivan@voicenet.com 97-feb-26
144
145 don't bill recurring fee if its not time! (was removed)
146 ivan@voicenet.com 97-mar-6
147
148 added -b option, send batch when done billing.
149 ivan@voicenet.com 97-apr-4
150
151 insecure dependency on line 179ish below needs to be fixed before bill is
152 used setuid
153 ivan@voicenet.com 97-jun-2
154
155 removed running of setup program (depriciated)
156 ivan@voicenet.com 97-jul-21
157
158 rewrote for new API, removed option to specify custnums (use FS::Bill 
159 instead), removed -v option (?)
160 ivan@voicenet.com 97-jul-22 - 23 - 25 -28
161 (need to add back in email stuff, look in /home/ivan/old/dbin/collect)
162
163 s/suidsetup/adminsuidsetup/, s/FS::Search/FS::Record/, added some batch
164 exporting stuff (which still needs to be generalized) and removed &idiot
165 ivan@sisd.com 98-may-27
166
167 $Log: bill,v $
168 Revision 1.6  1998-11-15 02:53:00  ivan
169 afterthought
170
171 Revision 1.4  1998/11/07 08:21:26  ivan
172 missing use
173
174 =cut
175
176