diff options
-rw-r--r-- | FS/FS/cust_main.pm | 43 | ||||
-rwxr-xr-x | FS/bin/freeside-overdue | 139 | ||||
-rw-r--r-- | httemplate/docs/billing.html | 7 |
3 files changed, 183 insertions, 6 deletions
diff --git a/FS/FS/cust_main.pm b/FS/FS/cust_main.pm index a36d125be..3995e6561 100644 --- a/FS/FS/cust_main.pm +++ b/FS/FS/cust_main.pm @@ -1416,10 +1416,25 @@ Returns the total owed for this customer on all invoices sub total_owed { my $self = shift; + $self->total_owed_date(2145859200); #12/31/2037 +} + +=item total_owed_date TIME + +Returns the total owed for this customer on all invoices with date earlier than +TIME. TIME is specified as a UNIX timestamp; see L<perlfunc/"time">). Also +see L<Time::Local> and L<Date::Parse> for conversion functions. + +=cut + +sub total_owed_date { + my $self = shift; + my $time = shift; my $total_bill = 0; - foreach my $cust_bill ( qsearch('cust_bill', { - 'custnum' => $self->custnum, - } ) ) { + foreach my $cust_bill ( + grep { $_->_date <= $time } + qsearch('cust_bill', { 'custnum' => $self->custnum, } ) + ) { $total_bill += $cust_bill->owed; } sprintf( "%.2f", $total_bill ); @@ -1575,6 +1590,26 @@ sub balance { ); } +=item balance_date TIME + +Returns the balance for this customer, only considering invoices with date +earlier than TIME (total_owed_date minus total_credited minus +total_unapplied_payments). TIME is specified as a UNIX timestamp; see +L<perlfunc/"time">). Also see L<Time::Local> and L<Date::Parse> for conversion +functions. + +=cut + +sub balance_date { + my $self = shift; + my $time = shift; + sprintf( "%.2f", + $self->total_owed_date($time) + - $self->total_credited + - $self->total_unapplied_payments + ); +} + =item invoicing_list [ ARRAYREF ] If an arguement is given, sets these email addresses as invoice recipients @@ -1881,7 +1916,7 @@ sub append_fuzzyfiles { =head1 VERSION -$Id: cust_main.pm,v 1.50 2001-12-16 23:50:10 ivan Exp $ +$Id: cust_main.pm,v 1.51 2001-12-26 11:17:49 ivan Exp $ =head1 BUGS diff --git a/FS/bin/freeside-overdue b/FS/bin/freeside-overdue new file mode 100755 index 000000000..541b8be03 --- /dev/null +++ b/FS/bin/freeside-overdue @@ -0,0 +1,139 @@ +#!/usr/bin/perl + +use strict; +use vars qw( $days_to_pay $cust_main $cust_pkg + $cust_svc $svc_acct ); +use Getopt::Std; +use FS::cust_main; +use FS::cust_pkg; +use FS::cust_svc; +use FS::svc_acct; +use FS::Record qw(qsearch qsearchs); +use FS::UID qw(adminsuidsetup); + +&untaint_argv; +my %opt; +getopts('ed:qpsc', \%opt); +my $user = shift or die &usage; + +adminsuidsetup $user; + +my $now = time; +my ($sec,$min,$hour,$mday,$mon,$year) = + (localtime($now) )[0,1,2,3,4,5]; +$mon++; +$year += 1900; + +foreach $cust_main ( qsearch('cust_main',{} ) ) { + + my ( $eyear, $emon, $eday ) = ( 2037, 12, 31 ); + if ( $cust_main->paydate =~ /^(\d{4})\-(\d{1,2})\-(\d{1,2})$/ + && $cust_main->payby eq 'BILL') { + ( $eyear, $emon, $eday ) = ( $1, $2, $3 ); + } + + if ( ( $opt{d} + && $cust_main->balance_date(time - $opt{d} * 86400) > 0 + && qsearchs( 'cust_pkg', { 'custnum' => $cust_main->custnum, + 'susp' => "" } ) ) + || ( $opt{e} + && $cust_main->payby eq 'BILL' + && ( $eyear < $year + || ( $eyear == $year && $emon < $mon ) ) ) + ) { + + unless ( $opt{q} ) { + print $cust_main->custnum, "\t", + $cust_main->last, "\t", $cust_main->first, "\t", + $cust_main->balance_date(time-$opt{d} * 86400); + } + + foreach $cust_pkg ( qsearch( 'cust_pkg', + { 'custnum' => $cust_main->custnum } ) ) { + + if ($opt{p} && ! grep { $_ eq 'POST' } $cust_main->invoicing_list ) { + print "\n\tAdding postal invoicing" unless $opt{q}; + my @invoicing_list = $cust_main->invoicing_list; + push @invoicing_list, 'POST'; + $cust_main->invoicing_list(\@invoicing_list); + } + + if ($opt{s}) { + print "\n\tSuspending pkgnum " . $cust_pkg->pkgnum unless $opt{q}; + $cust_pkg->suspend; + } + + if ($opt{c}) { + print "\n\tCancelling pkgnum " . $cust_pkg->pkgnum unless $opt{q}; + $cust_pkg->cancel; + } + + } + + print "\n" unless $opt{q}; + + } + +} + +sub untaint_argv { + foreach $_ ( $[ .. $#ARGV ) { + $ARGV[$_] =~ /^([\w\-\/]*)$/ || die "Illegal arguement \"$ARGV[$_]\""; + $ARGV[$_]=$1; + } +} + +sub usage { + die "Usage:\n\n freeside-overdue [ -e ] [ -d days ] [ -q ] [ -p ] [ -s ] [ -c ] user\n"; +} + + +=head1 NAME + +freeside-overdue - Perform actions on overdue and/or expired accounts. + +=head1 SYNOPSIS + + freeside-overdue [ -e ] [ -d days ] [ -q ] [ -p ] [ -s ] [ -c ] user + +=head1 DESCRIPTION + +Performs actions on overdue and/or expired accounts. + +Selection options (at least one selection option is required): + + -d: Customers with a balance due on invoices older than the supplied number + of days. Requires an integer argument. + + -e: Customers with a billing expiration date in the past. + +Action options: + + -q: Be quiet (by default, suspended accounts are printed). + + -p: Add postal invoicing to the relevant customers. + + -s: Suspend accounts. + + -c: Cancel accounts. + + user: From the mapsecrets file - see config.html from the base documentation + +=head1 CRONTAB + +Example crontab entries: + +20 4,16 * * * freeside-overdue -e -s user +20 4,16 * * * freeside-overdue -d 30 -p -q user +20 4,16 * * * freeside-overdue -d 60 user +20 4,16 * * * freeside-overdue -d 90 -s user +20 4,16 * * * freeside-overdue -d 120 -c user + +=head1 ORIGINAL AUTHORS + +Original disable-overdue version by mw/kwh: Mark W.? and Kristian Hoffmann ? + +=cut + +1; + diff --git a/httemplate/docs/billing.html b/httemplate/docs/billing.html index 7dc9aef2d..dcb90208a 100644 --- a/httemplate/docs/billing.html +++ b/httemplate/docs/billing.html @@ -22,12 +22,14 @@ </ul> </ul> <li>You can bill individual customers by clicking on the <i>Bill now</i> link on the main customer view. - <li> The <b>freeside-bill</b> script can be run daily to bill all customers. Usage:<pre>bill [ -c [ i ] ] [ -d <i>date</i> ] [ -b ] <i>user</i></pre> + <li> The <b>freeside-bill</b> script can be run daily to bill all customers. (link to manpage!) Usage:<pre>freeside-bill [ -c [ -p ] [ -a ] [ -i ] ] [ -d <i>date</i> ] <i>user</i></pre> <ul> <li>-c: Turn on collecting (you probably want this). + <li>-p: Apply unapplied payments and credits before collecting (you probably want this too) + <li>-a: Call collect even if there isn't a new invoice (probably a bad idea for daily use) <li>-i: Real-time billing (as opposed to bacth billing). Only relevant for credit cards. <li>-d: Pretend it is <i>date</i> (parsed by <a href="http://search.cpan.org/doc/GBARR/TimeDate-1.09/lib/Date/Parse.pm">Date::Parse</a>) - <li>-b: N/A + <li>user: as setup with freeside-adduser </ul> <br><br>Batch credit card processing <ul> @@ -63,5 +65,6 @@ All fields except paybatch are contained in the cust_pay_batch table. You can u <li>-d: Delete - Pays account and deletes record from cust_pay_batch. </ul> </ul> + <li>The <b>freeside-overdue</b> script can list, add postal invoicing, suspend or cancel overdue and/or expired accounts (link to manpage!). </ul> </body> |