import torrus 1.0.9
[freeside.git] / FS / FS / Cron / breakage.pm
index 6312667..6dd904d 100644 (file)
@@ -6,7 +6,7 @@ use vars qw( @EXPORT_OK );
 use FS::Conf;
 use FS::Record qw(qsearch);
 use FS::agent;
-#use FS::cust_main;
+use FS::cust_main;
 
 @EXPORT_OK = qw ( reconcile_breakage );
 
@@ -15,8 +15,7 @@ use FS::agent;
 # -l: debugging level
 
 sub reconcile_breakage {
-  return;
-  #nothing yet
+  my %opt = @_;
 
   my $conf = new FS::Conf;
 
@@ -25,14 +24,58 @@ sub reconcile_breakage {
     my $days = $conf->config('breakage-days', $agent->agentnum)
       or next;
 
-    #find customers w/a balance older than $days (and no activity since)
+    my $since = int( $^T - ($days * 86400) );
 
-    # - do a one time charge in the total amount of old unapplied payments.
-    #     'pkg' => 'Breakage', #or whatever.
-    #     'setuptax' => 'Y',
-    #     'classnum' => scalar($conf->config('breakage-pkg_class')),
-    # - use the new $cust_main->charge( 'bill_now' => 1 ) option to generate an invoice, etc.
-    # - apply_payments_and_credits
+    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";
+      }
+
+    }
 
   }