email referring customers on cancellation, RT#75756
[freeside.git] / bin / cust_pay_histogram
1 #!/usr/bin/perl -w
2
3 use strict;
4 use Getopt::Std;
5 use Date::Parse;
6 use FS::UID qw(adminsuidsetup);
7 use FS::Record qw( qsearch );
8 use FS::cust_pay;
9
10 &untaint_argv;  #what it sounds like  (eww)
11 use vars qw(%opt);
12 getopts("p:a:b:e:", \%opt);
13
14 my $user = shift or die &usage;
15 my $dbh = adminsuidsetup $user;
16
17 my @where = ();
18
19 push @where, 'agentnum = '. $dbh->quote($opt{a}) if $opt{a};
20 push @where, 'cust_pay.payby = '. $dbh->quote($opt{p}) if $opt{p};
21 push @where, 'cust_pay._date > '. $dbh->quote(str2time($opt{b})) if $opt{b};
22 push @where, 'cust_pay._date < '. $dbh->quote(str2time($opt{e})) if $opt{e};
23
24 my $extra_sql = scalar(@where) ? 'WHERE '. join(' AND ', @where) : '';
25 my $addl_from = 'LEFT JOIN cust_main USING( custnum )';
26
27 my @payrow = qsearch( { table     => 'cust_pay',
28                         hashref   => {},
29                         select    => 'count(*) AS quantity, paid',
30                         addl_from => $addl_from,
31                         extra_sql => $extra_sql,
32                         order_by  => 'GROUP BY paid',
33                       }
34                     );
35
36 my $max = 0;
37 my $sum = 0;
38 foreach (@payrow) {
39   $sum += $_->quantity;
40   $max = $_->quantity if $_->quantity > $max;
41 }
42 my $scale = int($max/60) + 1;
43
44 print "\n  PAYMENTS RECEIVED";
45 print " AFTER $opt{b}" if $opt{b};
46 print " UNTIL $opt{e}" if $opt{e};
47 print " VIA $opt{p}" if $opt{p};
48 print " BY AGENT $opt{a}" if $opt{a};
49 print "\n\n";
50 print "Total number of payments: $sum\n\n";
51 print "(each * represents $scale)\n\n" if $scale > 1;
52
53 foreach my $payrow ( @payrow ) {
54   print sprintf("%10.2f", $payrow->paid),
55         ": ",
56         sprintf("%6d", $payrow->quantity),
57         "| ",
58         '*' x($payrow->quantity/$scale),
59         "\n";
60 }
61
62 print "\n";
63
64
65 ###
66 # subroutines
67 ###
68
69 sub untaint_argv {
70   foreach $_ ( $[ .. $#ARGV ) { #untaint @ARGV
71     #$ARGV[$_] =~ /^([\w\-\/]*)$/ || die "Illegal arguement \"$ARGV[$_]\"";
72     # Date::Parse
73     $ARGV[$_] =~ /^(.*)$/ || die "Illegal arguement \"$ARGV[$_]\"";
74     $ARGV[$_]=$1;
75   }
76 }
77
78 sub usage {
79   die "Usage:\n\n  cust_pay_histogram [ -b 'begin_date' ] [ -e 'end_date' ] [ -p 'payby' ] [ -a agentnum ] user\n";
80 }
81
82 ###
83 # documentation
84 ###
85
86 =head1 NAME
87
88 cust_pay_histogram - Show a histogram of payments made for a date range.
89
90 =head1 SYNOPSIS
91
92   freeside-daily [ -b 'begin_date' ] [ -e 'end_date'] [ -p 'payby' ] [ -a agentnum ] user
93
94 =head1 DESCRIPTION
95
96 Displays a histogram of cust_pay records in the database.
97
98   -b: Include only payments since 'begin_date'.  Date is in any format Date::Parse is happy with, but be careful.
99
100   -e: Include only payments before 'end_date'.  Date is in any format Date::Parse is happy with, but be careful.
101
102   -p: Only process payments with the specified payby (I<CARD>, I<DCRD>, I<CHEK>, I<DCHK>, I<BILL>, I<COMP>, I<LECB>)
103
104   -a: Only process payments of customers with the specified agentnum
105
106 user: Freeside username
107
108 =head1 BUGS
109
110 =head1 SEE ALSO
111
112 L<FS::cust_pay>
113
114 =cut
115