summaryrefslogtreecommitdiff
path: root/FS/FS/Cron/breakage.pm
diff options
context:
space:
mode:
Diffstat (limited to 'FS/FS/Cron/breakage.pm')
-rw-r--r--FS/FS/Cron/breakage.pm84
1 files changed, 84 insertions, 0 deletions
diff --git a/FS/FS/Cron/breakage.pm b/FS/FS/Cron/breakage.pm
new file mode 100644
index 0000000..6dd904d
--- /dev/null
+++ b/FS/FS/Cron/breakage.pm
@@ -0,0 +1,84 @@
+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,
+ 'payby' => { op=>'!=', value=>'COMP', },
+ },
+ '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;