prepaid cdr pickup & bill daemon, RT#4184
authorivan <ivan>
Wed, 29 Oct 2008 08:03:08 +0000 (08:03 +0000)
committerivan <ivan>
Wed, 29 Oct 2008 08:03:08 +0000 (08:03 +0000)
FS/FS/cust_main.pm
FS/FS/part_pkg/voip_cdr.pm
FS/bin/freeside-cdrd [new file with mode: 0644]
init.d/freeside-init

index aa97d22..db70dac 100644 (file)
@@ -2399,9 +2399,13 @@ sub _make_lines {
   my $recur = 0;
   my $unitrecur = 0;
   my $sdate;
   my $recur = 0;
   my $unitrecur = 0;
   my $sdate;
-  if ( $part_pkg->getfield('freq') ne '0' &&
-       ! $cust_pkg->getfield('susp') &&
-       ( $cust_pkg->getfield('bill') || 0 ) <= $time
+  if ( ! $cust_pkg->getfield('susp') and
+           ( $part_pkg->getfield('freq') ne '0' &&
+             ( $cust_pkg->getfield('bill') || 0 ) <= $time
+           )
+        || ( $part_pkg->plan eq 'voip_cdr'
+              && $part_pkg->option('bill_every_call')
+           )
   ) {
 
     # XXX should this be a package event?  probably.  events are called
   ) {
 
     # XXX should this be a package event?  probably.  events are called
@@ -2418,42 +2422,50 @@ sub _make_lines {
     $sdate = $cust_pkg->bill || $cust_pkg->setup || $time;
 
     #over two params!  lets at least switch to a hashref for the rest...
     $sdate = $cust_pkg->bill || $cust_pkg->setup || $time;
 
     #over two params!  lets at least switch to a hashref for the rest...
-    my %param = ( 'precommit_hooks' => $precommit_hooks, );
+    my $increment_next_bill = ( $part_pkg->freq ne '0'
+                                && ( $cust_pkg->getfield('bill') || 0 ) <= $time
+                              );
+    my %param = ( 'precommit_hooks'     => $precommit_hooks,
+                  'increment_next_bill' => $increment_next_bill,
+                );
 
     $recur = eval { $cust_pkg->calc_recur( \$sdate, \@details, \%param ) };
     return "$@ running calc_recur for $cust_pkg\n"
       if ( $@ );
 
 
     $recur = eval { $cust_pkg->calc_recur( \$sdate, \@details, \%param ) };
     return "$@ running calc_recur for $cust_pkg\n"
       if ( $@ );
 
+    if ( $increment_next_bill ) {
   
   
-    #change this bit to use Date::Manip? CAREFUL with timezones (see
-    # mailing list archive)
-    my ($sec,$min,$hour,$mday,$mon,$year) =
-      (localtime($sdate) )[0,1,2,3,4,5];
-    
-    #pro-rating magic - if $recur_prog fiddles $sdate, want to use that
-    # only for figuring next bill date, nothing else, so, reset $sdate again
-    # here
-    $sdate = $cust_pkg->bill || $cust_pkg->setup || $time;
-    #no need, its in $hash{last_bill}# my $last_bill = $cust_pkg->last_bill;
-    $cust_pkg->last_bill($sdate);
-    
-    if ( $part_pkg->freq =~ /^\d+$/ ) {
-      $mon += $part_pkg->freq;
-      until ( $mon < 12 ) { $mon -= 12; $year++; }
-    } elsif ( $part_pkg->freq =~ /^(\d+)w$/ ) {
-      my $weeks = $1;
-      $mday += $weeks * 7;
-    } elsif ( $part_pkg->freq =~ /^(\d+)d$/ ) {
-      my $days = $1;
-      $mday += $days;
-    } elsif ( $part_pkg->freq =~ /^(\d+)h$/ ) {
-      my $hours = $1;
-      $hour += $hours;
-    } else {
-      return "unparsable frequency: ". $part_pkg->freq;
+      #change this bit to use Date::Manip? CAREFUL with timezones (see
+      # mailing list archive)
+      my ($sec,$min,$hour,$mday,$mon,$year) =
+        (localtime($sdate) )[0,1,2,3,4,5];
+
+      #pro-rating magic - if $recur_prog fiddles $sdate, want to use that
+      # only for figuring next bill date, nothing else, so, reset $sdate again
+      # here
+      $sdate = $cust_pkg->bill || $cust_pkg->setup || $time;
+      #no need, its in $hash{last_bill}# my $last_bill = $cust_pkg->last_bill;
+      $cust_pkg->last_bill($sdate);
+
+      if ( $part_pkg->freq =~ /^\d+$/ ) {
+        $mon += $part_pkg->freq;
+        until ( $mon < 12 ) { $mon -= 12; $year++; }
+      } elsif ( $part_pkg->freq =~ /^(\d+)w$/ ) {
+        my $weeks = $1;
+        $mday += $weeks * 7;
+      } elsif ( $part_pkg->freq =~ /^(\d+)d$/ ) {
+        my $days = $1;
+        $mday += $days;
+      } elsif ( $part_pkg->freq =~ /^(\d+)h$/ ) {
+        my $hours = $1;
+        $hour += $hours;
+      } else {
+        return "unparsable frequency: ". $part_pkg->freq;
+      }
+      $cust_pkg->setfield('bill',
+        timelocal_nocheck($sec,$min,$hour,$mday,$mon,$year));
+
     }
     }
-    $cust_pkg->setfield('bill',
-      timelocal_nocheck($sec,$min,$hour,$mday,$mon,$year));
 
   }
 
 
   }
 
index 1b565f2..a3b54ee 100644 (file)
@@ -395,7 +395,7 @@ sub calc_recur {
       # don't add it to invoice, don't set its status to NULL,
       # don't call downstream_csv or something on it...
       # but DO emit a warning...
       # don't add it to invoice, don't set its status to NULL,
       # don't call downstream_csv or something on it...
       # but DO emit a warning...
-      #if ( ! $rate_detail && ! scalar(@call_details) ) {
+      #if ( ! $rate_detail && ! scalar(@call_details) ) {}
       if ( ! $rate_detail && $charge eq '' ) {
 
         warn "no rate_detail found for CDR.acctid:  ". $cdr->acctid.
       if ( ! $rate_detail && $charge eq '' ) {
 
         warn "no rate_detail found for CDR.acctid:  ". $cdr->acctid.
@@ -509,8 +509,10 @@ sub calc_recur {
 
   } #if ( $spool_cdr && length($downstream_cdr) )
 
 
   } #if ( $spool_cdr && length($downstream_cdr) )
 
-  $self->option('recur_fee') + $charges;
+  $charges += $self->option('recur_fee')
+    if $param->{'increment_next_bill'};
 
 
+  $charges;
 }
 
 sub is_free {
 }
 
 sub is_free {
diff --git a/FS/bin/freeside-cdrd b/FS/bin/freeside-cdrd
new file mode 100644 (file)
index 0000000..ef420b5
--- /dev/null
@@ -0,0 +1,112 @@
+#!/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::cdr;
+use FS::cust_pkg;
+
+my $user = shift or die &usage;
+
+#daemonize1('freeside-sprepaidd', $user); #keep unique pid files w/multi installs
+daemonize1('freeside-cdrd');
+
+drop_root();
+
+adminsuidsetup($user);
+
+logfile( "%%%FREESIDE_LOG%%%/cdrd-log.". $FS::UID::datasrc );
+
+daemonize2();
+
+#--
+
+my $addl_from =
+  'LEFT JOIN part_pkg USING ( pkgpart ) '.
+  "LEFT JOIN part_pkg_option
+     ON ( cust_pkg.pkgpart = part_pkg_option.pkgpart
+          AND part_pkg_option.optionname = 'bill_every_call' )";
+
+#XXX should pay attention to disable_src for efficiency
+
+my $extra_sql =
+  "WHERE plan = 'voip_cdr' ".
+  " 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)
+        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
+                            )
+                  )
+    ) 
+  ";
+
+while (1) {
+
+  my $found = 0;
+  foreach my $cust_pkg ( 
+    qsearch( {
+      'select'    => 'cust_pkg.*, part_pkg.plan',
+      'table'     => 'cust_pkg',
+      'addl_from' => $addl_from,
+      'hashref'   => {},
+      'extra_sql' => $extra_sql,
+    } )
+  ) {
+
+    $found = 1;
+
+    my $work_cust_pkg = $cust_pkg;
+
+    my $cust_main = $cust_pkg->cust_main;
+
+    my $time = time;
+    $cust_main->bill_and_collect( 
+      'time'         => $time,
+      'invoice_time' => $time,
+      'actual_time'  => $time,
+      'check_freq'   => '1d', #well
+      #'debug'        => 1,
+    );
+
+  }
+
+  die "exiting" if sigterm() || sigint();
+  sleep 5; # unless $found;
+
+}
+
+#--
+
+sub usage { 
+  die "Usage:\n\n  freeside-prepaidd user\n";
+}
+
+=head1 NAME
+
+freeside-prepaidd - Real-time daemon for prepaid packages
+
+=head1 SYNOPSIS
+
+  freeside-prepaidd
+
+=head1 DESCRIPTION
+
+Runs continuously and suspends or cancels any prepaid customer packages which
+have passed their renewal date (next bill date).
+
+=head1 SEE ALSO
+
+=cut
+
+1;
index ddee5d2..1f3ce2b 100644 (file)
@@ -29,6 +29,10 @@ case "$1" in
         freeside-prepaidd $QUEUED_USER
         echo "done."
 
         freeside-prepaidd $QUEUED_USER
         echo "done."
 
+        echo -n "Starting freeside-cdrd: "
+        freeside-cdrd $QUEUED_USER
+        echo "done."
+
         for MACHINE in $SELFSERVICE_MACHINES; do
           echo -n "Starting freeside-selfservice-server to $MACHINE: "
           freeside-selfservice-server $SELFSERVICE_USER $MACHINE
         for MACHINE in $SELFSERVICE_MACHINES; do
           echo -n "Starting freeside-selfservice-server to $MACHINE: "
           freeside-selfservice-server $SELFSERVICE_USER $MACHINE
@@ -53,6 +57,10 @@ case "$1" in
         kill `cat /var/run/freeside-prepaidd.pid`
         echo "done."
 
         kill `cat /var/run/freeside-prepaidd.pid`
         echo "done."
 
+        echo -n "Stopping freeside-cdrd: "
+        kill `cat /var/run/freeside-cdrd.pid`
+        echo "done."
+
         if [ -e /var/run/freeside-selfservice-server.$SELFSERVICE_USER.pid ]
         then
           echo -n "Stopping (old) freeside-selfservice-server: "
         if [ -e /var/run/freeside-selfservice-server.$SELFSERVICE_USER.pid ]
         then
           echo -n "Stopping (old) freeside-selfservice-server: "