diff options
Diffstat (limited to 'FS/bin/freeside-cdrd')
| -rw-r--r-- | FS/bin/freeside-cdrd | 160 | 
1 files changed, 160 insertions, 0 deletions
| diff --git a/FS/bin/freeside-cdrd b/FS/bin/freeside-cdrd new file mode 100644 index 000000000..2cf75f31c --- /dev/null +++ b/FS/bin/freeside-cdrd @@ -0,0 +1,160 @@ +#!/usr/bin/perl -w + +use strict; +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; + +#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(); + +die "not running; no voip_cdr package defs w/ bill_every_call and customer pkgs" +  unless _shouldrun(); + +#-- + +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 +                            ) +                  ) +    ) +    AND 0 = ( +      SELECT COUNT(*) FROM queue +        WHERE queue.job = 'FS::cust_main::queued_bill' +          AND queue.custnum = cust_pkg.custnum +    ) +     +  "; +# don't repeatedly queue failures +#          AND status != 'failed' + +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; + +    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, +      'check_freq'   => '1d', #well +      #'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? +    } + +  } + +  myexit() if sigterm() || sigint(); +  sleep 1 unless $found; + +} + +#-- + +sub _shouldrun { + +  my $extra_sql = +    ' AND 0 < ( SELECT COUNT(*) 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-cdrd user\n"; +} + +=head1 NAME + +freeside-cdrd - Real-time daemon for CDRs + +=head1 SYNOPSIS + +  freeside-cdrd + +=head1 DESCRIPTION + +Runs continuously, searches for CDRs and bills customers who have VoIP +price plands with the B<bill_every_call> option set. + +=head1 SEE ALSO + +=cut + +1; | 
