diff options
Diffstat (limited to 'FS/bin/freeside-cdrrated')
-rw-r--r-- | FS/bin/freeside-cdrrated | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/FS/bin/freeside-cdrrated b/FS/bin/freeside-cdrrated new file mode 100644 index 000000000..131b56a7e --- /dev/null +++ b/FS/bin/freeside-cdrrated @@ -0,0 +1,178 @@ +#!/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::svc_phone; +use FS::part_pkg; + +my $user = shift or die &usage; + +daemonize1('freeside-cdrrated'); + +drop_root(); + +adminsuidsetup($user); + +logfile( "%%%FREESIDE_LOG%%%/cdrrated-log.". $FS::UID::datasrc ); + +daemonize2(); + +our $conf = new FS::Conf; + +die "not running; cdr-prerate conf option is off\n" + unless _shouldrun(); + +#-- + +my $extra_sql = ''; +my @cdrtypenums = $conf->config('cdr-prerate-cdrtypenums'); +if ( @cdrtypenums ) { + $extra_sql .= ' AND cdrtypenum IN ('. join(',', @cdrtypenums ). ')'; +} + +our %svcnum = (); +our %pkgpart = (); +our %part_pkg = (); + +#some false laziness w/freeside-cdrrewrited + +while (1) { + + my $found = 0; + foreach my $cdr ( + qsearch( { + 'table' => 'cdr', + 'hashref' => { 'freesidestatus' => '' }, + 'extra_sql' => $extra_sql. + ' LIMIT 1024'. #arbitrary, but don't eat too much memory + ' FOR UPDATE', + } ) + + ) { + + $found = 1; + + #find the matching service - some weird false laziness w/svc_phone::get_cdrs + + #in charged_party or src + #hmm... edge case; get_cdrs rating will match a src if a charged_party is + # present #but doesn't match a service... + my $number = $cdr->charged_party || $cdr->src; + + #technically default_prefix. phonenum or phonenum (or default_prefix without the + . phonenum) + #but for now we're just assuming default_prefix is +1 + my $prefix = '+1'; #$options{'default_prefix'}; + + $number = substr($number, length($prefix)) + if $prefix eq substr($number, 0, length($prefix)); + if ( $prefix && $prefix =~ /^\+(\d+)$/ ) { + $prefix = $1; + $number = substr($number, length($prefix)) + if $prefix eq substr($number, 0, length($prefix)); + } + + unless ( $svcnum{$number} ) { + #only phone number matching supported right now + my $svc_phone = qsearchs('svc_phone', { 'phonenum' => $number } ); + unless ( $svc_phone ) { + #XXX set freesideratestatus or something so we don't keep retrying? + next; + } + + $svcnum{$number} = $svc_phone->svcnum; + + my $cust_pkg = $svc_phone->cust_svc->cust_pkg; + unless ( $cust_pkg ) { + #XXX unlinked svc_phone? + # warn and also set freesideratestatus or somesuch? + next; + } + + #get the package, search through the part_pkg and linked for a voip_cdr def w/matching cdrtypenum (or no use_cdrtypenum) + my @part_pkg = + grep { $_->plan eq 'voip_cdr' + && ( ! length($_->option_cacheable('use_cdrtypenum')) + || $_->option_cacheable('use_cdrtypenum') + eq $cdr->cdrtypenum #eq otherwise 0 matches '' + ) + && ( ! length($_->option_cacheable('ignore_cdrtypenum')) + || $_->option_cacheable('ignore_cdrtypenum') + ne $cdr->cdrtypenum #ne otherwise 0 matches '' + ) + + } + $cust_pkg->part_pkg->self_and_bill_linked; + + if ( ! @part_pkg ) { + #XXX no package for this CDR + # warn and also set freesideratestatus or somesuch? + # or at least warn + next; + } elsif ( scalar(@part_pkg) > 1 ) { + warn "multiple package could rate CDR ". $cdr->acctid. "\n"; + # and also set freesideratestatus or somesuch? + next; + } + + $pkgpart{$number} = $part_pkg[0]->pkgpart; + $part_pkg{ $part_pkg[0]->pkgpart } ||= $part_pkg[0]; + + } + + #unless ( $part_pkg{$pkgpart{$number}} ) { + #} + + #XXX if $part_pkg->option('min_included') then we can't prerate this CDR + + my $error = $cdr->rate( + 'part_pkg' => $part_pkg{ $pkgpart{$number} }, + 'svcnum' => $svcnum{ $number }, + ); + if ( $error ) { + #XXX ??? + warn $error; + sleep 30; + } + + last if sigterm() || sigint(); + + } + + myexit() if sigterm() || sigint(); + sleep 5 unless $found; + +} + +#-- + +sub _shouldrun { + $conf->exists('cdr-prerate'); +} + +sub usage { + die "Usage:\n\n freeside-cdrrewrited user\n"; +} + +=head1 NAME + +freeside-cdrrated - Real-time daemon for CDR rating + +=head1 SYNOPSIS + + freeside-cdrrated + +=head1 DESCRIPTION + +Runs continuously, searches for CDRs and which can be pre-rated, and rates them. + +=head1 SEE ALSO + +cdr-prerate configuration setting + +=cut + +1; + |