Reverted menu-left-example.png back to original and cleaned up menu-top-example to...
[freeside.git] / FS / bin / freeside-cdrd
index ef420b5..a3c67f9 100644 (file)
@@ -1,11 +1,12 @@
 #!/usr/bin/perl -w
 
 use strict;
-use FS::Daemon qw(daemonize1 drop_root logfile daemonize2 sigint sigterm);
-use FS::UID qw(adminsuidsetup);
-use FS::Record qw(qsearch ); #qsearchs);
+use FS::Daemon ':all'; #daemonize1 drop_root daemonize2 myexit logfile sig*
+use FS::UID qw( adminsuidsetup );
+use FS::Record qw( qsearch ); #qsearchs);
 #use FS::cdr;
 use FS::cust_pkg;
+use FS::queue;
 
 my $user = shift or die &usage;
 
@@ -20,6 +21,9 @@ logfile( "%%%FREESIDE_LOG%%%/cdrd-log.". $FS::UID::datasrc );
 
 daemonize2();
 
+die "not running; no voip_cdr package defs w/ bill_every_call and customer pkgs"
+  unless _shouldrun();
+
 #--
 
 my $addl_from =
@@ -35,21 +39,32 @@ my $extra_sql =
   " AND optionvalue = '1' ".
   " AND ( susp   IS NULL OR susp   = 0)".
   " AND ( cancel IS NULL OR cancel = 0)".
-  " AND 0 < ( 
-      SELECT COUNT(*) FROM svc_phone LEFT JOIN cust_svc USING (svcnum)
+  " AND EXISTS ( 
+      SELECT 1 FROM svc_phone LEFT JOIN cust_svc USING (svcnum)
         WHERE cust_pkg.pkgnum = cust_svc.pkgnum
-          AND 0 < ( SELECT COUNT(*) FROM cdr
-                      WHERE ( freesidestatus IS NULL OR freesidestatus = '' )
-                        AND (    charged_party = svc_phone.phonenum
-                              OR charged_party = svc_phone.countrycode
-                                                 || svc_phone.phonenum
-                              OR src = svc_phone.phonenum
-                              OR src = svc_phone.countrycode
-                                       || svc_phone.phonenum
-                            )
-                  )
-    ) 
+          AND EXISTS ( SELECT 1 FROM cdr
+                         WHERE ( freesidestatus IS NULL OR freesidestatus = '' )
+                           AND (    charged_party = svc_phone.phonenum
+                                 OR charged_party = svc_phone.countrycode
+                                                    || svc_phone.phonenum
+                                 OR src = svc_phone.phonenum
+                                 OR src = svc_phone.countrycode
+                                          || svc_phone.phonenum
+                               )
+                         LIMIT 1
+                     )
+        LIMIT 1
+    )
+    AND NOT EXISTS (
+      SELECT 1 FROM queue
+        WHERE queue.job = 'FS::cust_main::queued_bill'
+          AND queue.custnum = cust_pkg.custnum
+        LIMIT 1
+    )
+    
   ";
+# don't repeatedly queue failures
+#          AND status != 'failed'
 
 while (1) {
 
@@ -66,12 +81,19 @@ while (1) {
 
     $found = 1;
 
-    my $work_cust_pkg = $cust_pkg;
+    #my $work_cust_pkg = $cust_pkg;
 
-    my $cust_main = $cust_pkg->cust_main;
+    #my $cust_main = $cust_pkg->cust_main;
 
     my $time = time;
-    $cust_main->bill_and_collect( 
+
+    my $job = new FS::queue {
+      'job'     => 'FS::cust_main::queued_bill',
+      'secure'  => 'Y',
+      'custnum' => $cust_pkg->custnum,
+    };
+    my $error = $job->insert(
+      'custnum'      => $cust_pkg->custnum, 
       'time'         => $time,
       'invoice_time' => $time,
       'actual_time'  => $time,
@@ -79,31 +101,60 @@ while (1) {
       #'debug'        => 1,
     );
 
+    if ( $error ) {
+      #die "FATAL: error inserting billing job: $error\n";
+      warn "WARNING: error inserting billing job (will retry in 30 seconds):".
+           " $error\n";
+      sleep 30; #i dunno, wait and see if the database comes back?
+    }
+
   }
 
-  die "exiting" if sigterm() || sigint();
-  sleep 5; # unless $found;
+  myexit() if sigterm() || sigint();
+  sleep 5 unless $found;
 
 }
 
 #--
 
+sub _shouldrun {
+
+  my $extra_sql =
+    ' AND EXISTS ( SELECT 1 FROM cust_pkg
+                     WHERE cust_pkg.pkgpart = part_pkg.pkgpart
+                       AND ( cust_pkg.cancel IS NULL OR cust_pkg.cancel = 0 )
+                 )
+    ';
+
+  my @part_pkg =
+    grep $_->option('bill_every_call', 'hush'),
+    qsearch({
+      'table'     => 'part_pkg',
+      'hashref'   => { 'plan' => 'voip_cdr' },
+      'extra_sql' => $extra_sql,
+    })
+  ;
+
+  scalar(@part_pkg);
+
+}
+
 sub usage { 
-  die "Usage:\n\n  freeside-prepaidd user\n";
+  die "Usage:\n\n  freeside-cdrd user\n";
 }
 
 =head1 NAME
 
-freeside-prepaidd - Real-time daemon for prepaid packages
+freeside-cdrd - Real-time daemon for CDRs
 
 =head1 SYNOPSIS
 
-  freeside-prepaidd
+  freeside-cdrd
 
 =head1 DESCRIPTION
 
-Runs continuously and suspends or cancels any prepaid customer packages which
-have passed their renewal date (next bill date).
+Runs continuously, searches for CDRs and bills customers who have VoIP
+price plands with the B<bill_every_call> option set.
 
 =head1 SEE ALSO