package FS::Cron::breakage; use strict; use base 'Exporter'; use vars qw( @EXPORT_OK ); use FS::Conf; use FS::Record qw(qsearch); use FS::agent; use FS::cust_main; @EXPORT_OK = qw ( reconcile_breakage ); #freeside-daily %opt # -v: enable debugging # -l: debugging level sub reconcile_breakage { my %opt = @_; my $conf = new FS::Conf; foreach my $agent (qsearch('agent', {})) { my $days = $conf->config('breakage-days', $agent->agentnum) or next; my $since = int( $^T - ($days * 86400) ); warn 'searching '. $agent->agent. " for customers with unapplied payments more than $days days old\n" if $opt{'v'}; #find customers w/negative balance older than $days (and no activity since) # and no activity (invoices/payments/credits/refunds) newer than $since # (XXX except antother breakage invoice???) my $extra_sql = ' AND 0 > '. FS::cust_main->balance_sql. ' AND '. join(' AND ', map { " NOT EXISTS ( SELECT 1 FROM $_ WHERE $_.custnum = cust_main.custnum AND _date >= $since ) " } qw( cust_bill cust_pay cust_credit cust_refund ) ); my @customers = qsearch({ 'table' => 'cust_main', 'hashref' => { 'agentnum' => $agent->agentnum, 'complimentary' => { op=>'!=', value=>'Y', }, }, 'extra_sql' => $extra_sql, }); #and then create a "breakage" charge & invoice for them foreach my $cust_main ( @customers ) { warn 'reconciling breakage for customer '. $cust_main->custnum. ': '. $cust_main->name. "\n" if $opt{'v'}; my $error = $cust_main->charge({ 'amount' => sprintf('%.2f', 0 - $cust_main->balance ), 'pkg' => 'Breakage', 'comment' => 'breakage reconciliation', 'classnum' => scalar($conf->config('breakage-pkg_class')), 'setuptax' => 'Y', 'bill_now' => 1, }) || $cust_main->apply_payments_and_credits; if ( $error ) { warn "error charging for breakage reconciliation: $error\n"; } } } } 1;