#!/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:qplsc', \%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); } # if ( $opt{l} ) { # print "\n\tCharging late fee of \$$opt{l}" unless $opt{q}; # # } 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 ] [ -l amount ] [ -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 ] [ -l amount ] [ -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, selected accounts are printed). -p: Add postal invoicing to the relevant customers. -l: Add a charge of the given amount 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: # suspend expired accounts 20 4 * * * freeside-overdue -e -s user # quietly add postal invoicing to customers over 30 days past due 20 4 * * * freeside-overdue -d 30 -p -q user # suspend accounts and charge a $10.23 fee for customers over 60 days past due 20 4 * * * freeside-overdue -d 60 -s -l 10.23 user # cancel accounts over 90 days past due 20 4 * * * freeside-overdue -d 90 -c user =head1 ORIGINAL AUTHORS Original disable-overdue version by mw/kwh: Mark W.? and Kristian Hoffmann ? =cut 1;