yes i have crazy customers with 8-digit customer numbers
[freeside.git] / FS / bin / freeside-receivables-report
1 #!/usr/bin/perl -Tw
2
3 use strict;
4 use Date::Parse;
5 use Time::Local;
6 use Getopt::Std;
7 use Text::Template;
8 use FS::Conf;
9 use FS::UID qw(adminsuidsetup);
10 use FS::Record qw(qsearch);
11 use FS::cust_main;
12
13 # Set the mail program
14 my $mail_program = "/usr/sbin/sendmail -t -n"; 
15
16 &untaint_argv;  #what it sounds like  (eww)
17 use vars qw($opt_v $opt_p $opt_m $opt_e $opt_t $report_lines $report_template @buf);
18 getopts("vpmet:");      #switches
19
20 #we're at now now (and later).
21 my($_date)= $^T;
22
23 # Get the current month
24 my ($sec,$min,$hour,$mday,$mon,$year) =
25         (localtime($_date) )[0,1,2,3,4,5]; 
26 $mon++;
27 $year += 1900;
28
29 # Login to the database
30 my $user = shift or die &usage;
31 adminsuidsetup $user;
32
33 # Get the needed configuration files
34 my $conf = new FS::Conf;
35 my $lpr = $conf->config('lpr');
36 my $email = $conf->config('email');
37 my @report_template = $conf->config('report_template')
38   or die "cannot load config file report_template";
39 $report_lines = 0;
40   foreach ( grep /report_lines\(\d+\)/, @report_template ) { #kludgy :/
41   /report_lines\((\d+)\)/;
42   $report_lines += $1;
43 }
44 die "no report_lines() functions in template?" unless $report_lines;
45 $report_template = new Text::Template (
46   TYPE   => 'ARRAY',
47   SOURCE => [ map "$_\n", @report_template ],
48 ) or die "can't create new Text::Template object: $Text::Template::ERROR";
49
50
51 my(@customers)=qsearch('cust_main',{});
52 if (scalar(@customers) == 0)
53 {
54         exit 1;
55 }
56
57 # Open print and email pipes
58 # $lpr and opt_p for printing
59 # $email and opt_m for email
60
61 if ($lpr && $opt_p)
62 {
63         open(LPR, "|$lpr");
64 }
65
66 if ($email && $opt_m)
67 {
68         open (MAIL, "|$mail_program");
69         print MAIL <<END
70 To: $email
71 From: Account Processor
72 Subject: Receivables
73
74
75 END
76 }
77
78 my $total = 0;
79
80
81 # Now I can start looping
82 foreach my $customer (@customers)
83 {
84   my $custnum = $customer->getfield('custnum');
85   my $first = $customer->getfield('first');
86   my $last = $customer->getfield('last');
87   my $company = $customer->getfield('company');
88   my $daytime = $customer->getfield('daytime');
89   my $balance = $customer->balance;
90
91
92   if ($balance != 0) {
93     $total += $balance;
94     push @buf, sprintf(qq{%8d %-32.32s %12s %9.2f},
95       $custnum,
96       $first . " " . $last . "   " . $company,
97       $daytime,
98       $balance);
99
100   }
101
102 }
103
104 push @buf, ('', sprintf(qq{%61s}, "========="), sprintf(qq{%61.2f}, $total));
105
106 sub FS::receivables_report::_template::report_lines {
107   my $lines = shift;
108   map {
109     scalar(@buf) ? shift @buf : '' ;
110   }
111   ( 1 .. $lines );
112 }
113
114 $FS::receivables_report::_template::title = " R E C E I V A B L E S ";
115 $FS::receivables_report::_template::title = $opt_t if $opt_t;
116 $FS::receivables_report::_template::page = 1;
117 $FS::receivables_report::_template::date = $_date;
118 $FS::receivables_report::_template::date = $_date;
119 $FS::receivables_report::_template::total_pages = 
120   int( scalar(@buf) / $report_lines);
121 $FS::receivables_report::_template::total_pages++ if scalar(@buf) % $report_lines;
122
123 my @report;
124 while (@buf) {
125   push @report, split("\n", 
126     $report_template->fill_in( PACKAGE => 'FS::receivables_report::_template' )
127   );
128   $FS::receivables_report::_template::page++;
129 }
130
131 if ($opt_v) {
132   print map "$_\n", @report;
133 }
134 if($lpr && $opt_p)
135 {
136   print LPR map "$_\n", @report;
137   print LPR "\f" if $opt_e;
138   close LPR || die "Could not close printer: $lpr\n";
139 }
140 if($email && $opt_m)
141 {
142   print MAIL map "$_\n", @report;
143   close MAIL || die "Could not close printer: $email\n";
144 }
145
146
147 # subroutines
148
149 sub untaint_argv {
150   foreach $_ ( $[ .. $#ARGV ) { #untaint @ARGV
151     $ARGV[$_] =~ /^([\w\-\/ ]*)$/ || die "Illegal argument \"$ARGV[$_]\"";
152     $ARGV[$_]=$1;
153   }
154 }
155
156 sub usage {
157   die "Usage:\n\n  freeside-receivables-report [-v] [-p] [-e] user\n";
158 }
159
160 =head1 NAME
161
162 freeside-receivables-report - Prints or emails outstanding receivables.
163
164 =head1 SYNOPSIS
165
166   freeside-receivables-report [-v] [-p] [-m] [-e] [-t "title"] user
167
168 =head1 DESCRIPTION
169
170 Prints or emails outstanding receivables
171
172 -v: Verbose - Prints records to STDOUT.
173
174 -p: Print to printer lpr as found in the conf directory.
175
176 -m: Mail output to user found in the Conf email file.
177
178 -e: Print a final form feed to the printer.
179
180 -t: supply a title for the top of each page.
181
182 user: From the mapsecrets file - see config.html from the base documentation
183
184 =head1 VERSION
185
186 $Id: freeside-receivables-report,v 1.2 2002-03-05 09:44:09 ivan Exp $
187
188 =head1 BUGS
189
190 Yes..... Use at your own risk. No guarantees or warrantees of any
191 kind apply to this program. Parts of this program are hacked from
192 other GNU licensed software created mainly by Ivan Kohler.
193
194 This is released under the GNU Public License. See www.gnu.org
195 for more information regarding this license.
196
197 =head1 SEE ALSO
198
199 L<FS::cust_main>, config.html from the base documentation
200
201 =head1 HISTORY
202
203 griff@aver-computer.com July 99
204
205 $Log: freeside-receivables-report,v $
206 Revision 1.2  2002-03-05 09:44:09  ivan
207 yes i have crazy customers with 8-digit customer numbers
208
209 Revision 1.1  2002/02/22 23:18:32  jeff
210 add some reporting features
211
212 Revision 1.1  2000/09/20 19:25:19  jeff
213 local modifications
214
215 Revision 1.1  2000/05/13 21:57:56  ivan
216 add print_batch script from Joel Griffiths
217
218
219 =cut
220
221