4 use FS::Daemon ':all'; #daemonize1 drop_root daemonize2 myexit logfile sig*
5 use FS::UID qw( adminsuidsetup );
6 use FS::Record qw( qsearch qsearchs );
11 my $user = shift or die &usage;
13 daemonize1('freeside-cdrrated');
17 adminsuidsetup($user);
19 logfile( "%%%FREESIDE_LOG%%%/cdrrated-log.". $FS::UID::datasrc );
23 our $conf = new FS::Conf;
25 die "not running; cdr-prerate conf option is off\n"
31 my @cdrtypenums = $conf->config('cdr-prerate-cdrtypenums');
33 $extra_sql .= ' AND cdrtypenum IN ('. join(',', @cdrtypenums ). ')';
40 #some false laziness w/freeside-cdrrewrited
48 'hashref' => { 'freesidestatus' => '' },
49 'extra_sql' => $extra_sql.
50 ' LIMIT 1024'. #arbitrary, but don't eat too much memory
58 #find the matching service - some weird false laziness w/svc_phone::get_cdrs
60 #in charged_party or src
61 #hmm... edge case; get_cdrs rating will match a src if a charged_party is
62 # present #but doesn't match a service...
63 my $number = $cdr->charged_party || $cdr->src;
65 #technically default_prefix. phonenum or phonenum (or default_prefix without the + . phonenum)
66 #but for now we're just assuming default_prefix is +1
67 my $prefix = '+1'; #$options{'default_prefix'};
69 $number = substr($number, length($prefix))
70 if $prefix eq substr($number, 0, length($prefix));
71 if ( $prefix && $prefix =~ /^\+(\d+)$/ ) {
73 $number = substr($number, length($prefix))
74 if $prefix eq substr($number, 0, length($prefix));
77 unless ( $svcnum{$number} ) {
78 #only phone number matching supported right now
79 my $svc_phone = qsearchs('svc_phone', { 'phonenum' => $number } );
80 unless ( $svc_phone ) {
81 #XXX set freesideratestatus or something so we don't keep retrying?
85 $svcnum{$number} = $svc_phone->svcnum;
87 my $cust_pkg = $svc_phone->cust_svc->cust_pkg;
88 unless ( $cust_pkg ) {
89 #XXX unlinked svc_phone?
90 # warn and also set freesideratestatus or somesuch?
94 #get the package, search through the part_pkg and linked for a voip_cdr def w/matching cdrtypenum (or no use_cdrtypenum)
96 grep { $_->plan eq 'voip_cdr'
97 && ( ! length($_->option_cacheable('use_cdrtypenum'))
98 || $_->option_cacheable('use_cdrtypenum')
99 eq $cdr->cdrtypenum #eq otherwise 0 matches ''
101 && ( ! length($_->option_cacheable('ignore_cdrtypenum'))
102 || $_->option_cacheable('ignore_cdrtypenum')
103 ne $cdr->cdrtypenum #ne otherwise 0 matches ''
107 $cust_pkg->part_pkg->self_and_bill_linked;
110 #XXX no package for this CDR
111 # warn and also set freesideratestatus or somesuch?
114 } elsif ( scalar(@part_pkg) > 1 ) {
115 warn "multiple package could rate CDR ". $cdr->acctid. "\n";
116 # and also set freesideratestatus or somesuch?
120 $pkgpart{$number} = $part_pkg[0]->pkgpart;
121 $part_pkg{ $part_pkg[0]->pkgpart } ||= $part_pkg[0];
125 #unless ( $part_pkg{$pkgpart{$number}} ) {
128 #XXX if $part_pkg->option('min_included') then we can't prerate this CDR
130 my $error = $cdr->rate(
131 'part_pkg' => $part_pkg{ $pkgpart{$number} },
132 'svcnum' => $svcnum{ $number },
140 last if sigterm() || sigint();
144 myexit() if sigterm() || sigint();
145 sleep 5 unless $found;
152 $conf->exists('cdr-prerate');
156 die "Usage:\n\n freeside-cdrrewrited user\n";
161 freeside-cdrrated - Real-time daemon for CDR rating
169 Runs continuously, searches for CDRs and which can be pre-rated, and rates them.
173 cdr-prerate configuration setting