diff options
author | Ivan Kohler <ivan@freeside.biz> | 2013-02-25 19:31:06 -0800 |
---|---|---|
committer | Ivan Kohler <ivan@freeside.biz> | 2013-02-25 19:31:06 -0800 |
commit | bf5576362a192f74efe6cedc4ff258842c34bbcd (patch) | |
tree | a0a50c5749fd6b5d7a1851b57aebb9bc44476875 /FS | |
parent | 3cec6fec210ce9b7a5528e3c6a8d85e213a0883d (diff) | |
parent | db5e7f34b1e17ae6ce8909062537cc2fb98ca30d (diff) |
Merge branch 'master' of git.freeside.biz:/home/git/freeside
Diffstat (limited to 'FS')
-rw-r--r-- | FS/FS/ClientAPI/MyAccount.pm | 50 | ||||
-rw-r--r-- | FS/FS/Conf.pm | 35 | ||||
-rw-r--r-- | FS/FS/Schema.pm | 1 | ||||
-rw-r--r-- | FS/FS/cdr.pm | 14 | ||||
-rw-r--r-- | FS/FS/cdr/taqua62.pm | 4 | ||||
-rw-r--r-- | FS/FS/part_export/huawei_hlr.pm | 32 | ||||
-rw-r--r-- | FS/FS/part_pkg/voip_cdr.pm | 26 | ||||
-rw-r--r-- | FS/FS/pay_batch/BoM.pm | 10 | ||||
-rw-r--r-- | FS/FS/rate.pm | 29 | ||||
-rw-r--r-- | FS/FS/rate_region.pm | 6 | ||||
-rw-r--r-- | FS/FS/svc_phone.pm | 29 | ||||
-rw-r--r-- | FS/bin/freeside-cdrrewrited | 60 |
12 files changed, 226 insertions, 70 deletions
diff --git a/FS/FS/ClientAPI/MyAccount.pm b/FS/FS/ClientAPI/MyAccount.pm index faf377874..38139e11b 100644 --- a/FS/FS/ClientAPI/MyAccount.pm +++ b/FS/FS/ClientAPI/MyAccount.pm @@ -1723,7 +1723,34 @@ sub list_svcs { } else { $hash{'name'} = $cust_main->name; } + } elsif ( $svcdb eq 'svc_phone' ) { + # could potentially show lots of things... + $hash{'outbound'} = 1; + $hash{'inbound'} = 0; + if ( $part_pkg->plan eq 'voip_inbound' ) { + $hash{'outbound'} = 0; + $hash{'inbound'} = 1; + } elsif ( $part_pkg->option('selfservice_inbound_format') + or $conf->config('selfservice-default_inbound_cdr_format') + ) { + $hash{'inbound'} = 1; + } + foreach (qw(inbound outbound)) { + # hmm...we can't filter by status here, because there might + # not be cdr_terminations at all. have to go by date. + # find all since the last bill date. + # XXX cdr types? we are going to need them. + if ( $hash{$_} ) { + my $sum_cdr = $svc_x->sum_cdrs( + 'inbound' => ( $_ eq 'inbound' ? 1 : 0 ), + 'begin' => ($cust_pkg->last_bill || 0), + 'nonzero' => 1, + ); + $hash{$_} = $sum_cdr->hashref; + } + } } + # elsif ( $svcdb eq 'svc_phone' || $svcdb eq 'svc_port' ) { # %hash = ( # %hash, @@ -1996,7 +2023,7 @@ sub _list_cdr_usage { # we have to return the results all at once... my($svc_phone, $begin, $end, %opt) = @_; map [ $_->downstream_csv(%opt, 'keeparray' => 1) ], - $svc_phone->get_cdrs( 'begin'=>$begin, 'end'=>$end, ); + $svc_phone->get_cdrs( 'begin'=>$begin, 'end'=>$end, %opt ); } sub list_cdr_usage { @@ -2026,18 +2053,21 @@ sub _usage_details { my %callback_opt; my $header = []; if ( $svcdb eq 'svc_phone' ) { - my $format = $cust_pkg->part_pkg->option('output_format') || ''; - $format = '' if $format =~ /^sum_/; - # sensible default if there is no format or it's a summary format - if ( $cust_pkg->part_pkg->plan eq 'voip_inbound' ) { - $format ||= 'source_default'; + my $conf = FS::Conf->new; + my $format = ''; + if ( $p->{inbound} ) { + $format = $cust_pkg->part_pkg->option('selfservice_inbound_format') + || $conf->config('selfservice-default_inbound_cdr_format') + || 'source_default'; $callback_opt{inbound} = 1; + } else { + $format = $cust_pkg->part_pkg->option('selfservice_format') + || $conf->config('selfservice-default_cdr_format') + || 'default'; } - else { - $format ||= 'default'; - } - + $callback_opt{format} = $format; + $callback_opt{use_clid} = 1; $header = [ split(',', FS::cdr::invoice_header($format) ) ]; } diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm index 809333c65..2931f3501 100644 --- a/FS/FS/Conf.pm +++ b/FS/FS/Conf.pm @@ -717,6 +717,18 @@ my %batch_gateway_options = ( }, ); +my @cdr_formats = ( + '' => '', + 'default' => 'Default', + 'source_default' => 'Default with source', + 'accountcode_default' => 'Default plus accountcode', + 'description_default' => 'Default with description field as destination', + 'basic' => 'Basic', + 'simple' => 'Simple', + 'simple2' => 'Simple with source', + 'accountcode_simple' => 'Simple with accountcode', +); + # takes the reason class (C, R, S) as an argument sub reason_type_options { my $reason_class = shift; @@ -4760,6 +4772,13 @@ and customer address. Include units.', }, { + 'key' => 'cdr-taqua-callerid_rewrite', + 'section' => 'telephony', + 'description' => 'For the Taqua CDR format, pull Caller ID blocking information from secondary CDRs.', + 'type' => 'checkbox', + }, + + { 'key' => 'cdr-asterisk_australia_rewrite', 'section' => 'telephony', 'description' => 'For Asterisk CDRs, assign CDR type numbers based on Australian conventions.', @@ -5351,6 +5370,22 @@ and customer address. Include units.', }, { + 'key' => 'selfservice-default_cdr_format', + 'section' => 'self-service', + 'description' => 'Format for showing outbound CDRs in self-service. The per-package option overrides this.', + 'type' => 'select', + 'select_hash' => \@cdr_formats, + }, + + { + 'key' => 'selfservice-default_inbound_cdr_format', + 'section' => 'self-service', + 'description' => 'Format for showing inbound CDRs in self-service. The per-package option overrides this. Leave blank to avoid showing these CDRs.', + 'type' => 'select', + 'select_hash' => \@cdr_formats, + }, + + { 'key' => 'logout-timeout', 'section' => 'UI', 'description' => 'If set, automatically log users out of the backoffice after this many minutes.', diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm index 6c7453d1c..774dcd239 100644 --- a/FS/FS/Schema.pm +++ b/FS/FS/Schema.pm @@ -3056,6 +3056,7 @@ sub tables_hashref { 'columns' => [ 'regionnum', 'serial', '', '', '', '', 'regionname', 'varchar', '', $char_d, '', '', + 'exact_match', 'char', 'NULL', 1, '', '', ], 'primary_key' => 'regionnum', 'unique' => [], diff --git a/FS/FS/cdr.pm b/FS/FS/cdr.pm index fedf28aa6..5e986ab50 100644 --- a/FS/FS/cdr.pm +++ b/FS/FS/cdr.pm @@ -1173,6 +1173,8 @@ sub export_formats { length($price) ? ($opt{money_char} . $price) : ''; }; + my $src_sub = sub { $_[0]->clid || $_[0]->src }; + %export_formats = ( 'simple' => [ sub { time2str($date_format, shift->calldate_unix ) }, #DATE @@ -1187,7 +1189,7 @@ sub export_formats { sub { time2str($date_format, shift->calldate_unix ) }, #DATE sub { time2str('%r', shift->calldate_unix ) }, #TIME #'userfield', #USER - 'src', #called from + $src_sub, #called from 'dst', #NUMBER_DIALED $duration_sub, #DURATION #sub { sprintf('%.3f', shift->upstream_price ) }, #PRICE @@ -1196,7 +1198,7 @@ sub export_formats { 'accountcode_simple' => [ sub { time2str($date_format, shift->calldate_unix ) }, #DATE sub { time2str('%r', shift->calldate_unix ) }, #TIME - 'src', #called from + $src_sub, #called from 'accountcode', #NUMBER_DIALED $duration_sub, #DURATION $price_sub, @@ -1204,14 +1206,14 @@ sub export_formats { 'sum_duration' => [ # for summary formats, the CDR is a fictitious object containing the # total billsec and the phone number of the service - 'src', + $src_sub, sub { my($cdr, %opt) = @_; $opt{ratename} }, sub { my($cdr, %opt) = @_; $opt{count} }, sub { my($cdr, %opt) = @_; int($opt{seconds}/60).'m' }, $price_sub, ], 'sum_count' => [ - 'src', + $src_sub, sub { my($cdr, %opt) = @_; $opt{ratename} }, sub { my($cdr, %opt) = @_; $opt{count} }, $price_sub, @@ -1245,7 +1247,7 @@ sub export_formats { $price_sub, ], ); - $export_formats{'source_default'} = [ 'src', @{ $export_formats{'default'} }, ]; + $export_formats{'source_default'} = [ $src_sub, @{ $export_formats{'default'} }, ]; $export_formats{'accountcode_default'} = [ @{ $export_formats{'default'} }[0,1], 'accountcode', @@ -1253,7 +1255,7 @@ sub export_formats { ]; my @default = @{ $export_formats{'default'} }; $export_formats{'description_default'} = - [ 'src', @default[0..2], + [ $src_sub, @default[0..2], sub { my($cdr, %opt) = @_; $cdr->description }, @default[4,5] ]; diff --git a/FS/FS/cdr/taqua62.pm b/FS/FS/cdr/taqua62.pm index 862018e9c..aa9463008 100644 --- a/FS/FS/cdr/taqua62.pm +++ b/FS/FS/cdr/taqua62.pm @@ -20,7 +20,9 @@ use FS::cdr qw(_cdr_date_parser_maker); my($cdr, $field, $conf, $hashref) = @_; $hashref->{skiprow} = 1 unless ($field == 0 && $cdr->disposition == 100 ) #regular CDR - || ($field == 1 && $cdr->lastapp eq 'acctcode'); #accountcode + || ($field == 1 && $cdr->lastapp eq 'acctcode') #accountcode + || ($field == 1 && $cdr->lastapp eq 'CallerId') #CID blocking + ; $cdr->cdrtypenum($field); }, diff --git a/FS/FS/part_export/huawei_hlr.pm b/FS/FS/part_export/huawei_hlr.pm index fb3b6790a..d231567c1 100644 --- a/FS/FS/part_export/huawei_hlr.pm +++ b/FS/FS/part_export/huawei_hlr.pm @@ -18,6 +18,7 @@ tie my %options, 'Tie::IxHash', 'pwd' => { label=>'Operator password' }, 'tplid' => { label=>'Template number' }, 'hlrsn' => { label=>'HLR serial number' }, + 'timeout' => { label=>'Timeout (seconds)', default => 120 }, 'debug' => { label=>'Enable debugging', type=>'checkbox' }, ; @@ -36,13 +37,13 @@ sub _export_insert { my( $self, $svc_phone ) = (shift, shift); # svc_phone::check should ensure phonenum and sim_imsi are numeric my @command = ( - 'ADD TPLSUB', IMSI => '"'.$svc_phone->sim_imsi.'"', - ISDN => '"'.$svc_phone->phonenum.'"', + ISDN => '"'.$svc_phone->countrycode.$svc_phone->phonenum.'"', TPLID => $self->option('tplid'), ); unshift @command, 'HLRSN', $self->option('hlrsn') if $self->option('hlrsn'); + unshift @command, 'ADD TPLSUB'; my $err_or_queue = $self->queue_command($svc_phone->svcnum, @command); ref($err_or_queue) ? '' : $err_or_queue; } @@ -53,7 +54,7 @@ sub _export_replace { if ( $new->sim_imsi ne $old->sim_imsi ) { my @command = ( 'MOD IMSI', - ISDN => '"'.$old->phonenum.'"', + ISDN => '"'.$old->countrycode.$old->phonenum.'"', IMSI => '"'.$old->sim_imsi.'"', NEWIMSI => '"'.$new->sim_imsi.'"', ); @@ -61,11 +62,12 @@ sub _export_replace { return $err_or_queue unless ref $err_or_queue; $depend_jobnum = $err_or_queue->jobnum; } - if ( $new->phonenum ne $old->phonenum ) { + if ( $new->countrycode ne $old->countrycode or + $new->phonenum ne $old->phonenum ) { my @command = ( 'MOD ISDN', - ISDN => '"'.$old->phonenum.'"', - NEWISDN => '"'.$new->phonenum.'"', + ISDN => '"'.$old->countrycode.$old->phonenum.'"', + NEWISDN => '"'.$new->countrycode.$new->phonenum.'"', ); my $err_or_queue = $self->queue_command($new->svcnum, @command); return $err_or_queue unless ref $err_or_queue; @@ -94,7 +96,7 @@ sub _export_lock { my @command = ( 'MOD LCK', IMSI => '"'.$svc_phone->sim_imsi.'"', - ISDN => '"'.$svc_phone->phonenum.'"', + ISDN => '"'.$svc_phone->countrycode.$svc_phone->phonenum.'"', IC => $lockstate, OC => $lockstate, GPRSLOCK=> $lockstate, @@ -107,8 +109,8 @@ sub _export_delete { my( $self, $svc_phone ) = (shift, shift); my @command = ( 'RMV SUB', - IMSI => '"'.$svc_phone->sim_imsi.'"', - ISDN => '"'.$svc_phone->phonenum.'"', + #IMSI => '"'.$svc_phone->sim_imsi.'"', + ISDN => '"'.$svc_phone->countrycode.$svc_phone->phonenum.'"', ); my $err_or_queue = $self->queue_command($svc_phone->svcnum, @command); ref($err_or_queue) ? '' : $err_or_queue; @@ -179,15 +181,16 @@ sub command { $string .= shift(@param) . '=' . shift(@param); $string .= ',' if @param; } - $string .= "\n"; + $string .= "\n;"; my @result; eval { # timeout local $SIG{ALRM} = sub { die "timeout\n" }; - alarm ($self->option('timeout') || 30); + alarm ($self->option('timeout') || 120); warn "Sending to server:\n$string\n\n" if $DEBUG; $socket->print($string); warn "Received:\n"; my $line; + local $/ = "\r\n"; do { $line = $socket->getline(); warn $line if $DEBUG; @@ -203,11 +206,10 @@ sub command { return { error => $@ }; } else { #+++ HLR9820 <date> <time>\n - # skip empty lines my $header = shift(@result); - return { error => 'malformed response: '.$header } - unless $header =~ /^\+\+\+/; - $return{header} = $header; + $header =~ /(\+\+\+.*)/ + or return { error => 'malformed response: '.$header }; + $return{header} = $1; #SMU #<serial number>\n $return{smu} = shift(@result); #%%<command string>%%\n diff --git a/FS/FS/part_pkg/voip_cdr.pm b/FS/FS/part_pkg/voip_cdr.pm index aae51e96c..04098a897 100644 --- a/FS/FS/part_pkg/voip_cdr.pm +++ b/FS/FS/part_pkg/voip_cdr.pm @@ -51,6 +51,11 @@ tie my %unrateable_opts, 'Tie::IxHash', 2 => 'Flag for later review', ; +tie my %detail_formats, 'Tie::IxHash', + '' => '', + FS::cdr::invoice_formats() +; + %info = ( 'name' => 'VoIP rating by plan of CDR records in an internal (or external) SQL table', 'shortname' => 'VoIP/telco CDR rating (standard)', @@ -211,12 +216,25 @@ tie my %unrateable_opts, 'Tie::IxHash', }, #false laziness w/cdr_termination.pm - 'output_format' => { 'name' => 'CDR invoice display format', + 'output_format' => { 'name' => 'CDR display format for invoices', 'type' => 'select', - 'select_options' => { FS::cdr::invoice_formats() }, + 'select_options' => \%detail_formats, 'default' => 'default', #XXX test }, + 'selfservice_format' => + { 'name' => 'CDR display format for selfservice', + 'type' => 'select', + 'select_options' => \%detail_formats, + 'default' => 'default' + }, + 'selfservice_inbound_format' => + { 'name' => 'Inbound CDR display format for selfservice', + 'type' => 'select', + 'select_options' => \%detail_formats, + 'default' => '' + }, + 'usage_section' => { 'name' => 'Section in which to place usage charges (whether separated or not): ', }, @@ -297,7 +315,9 @@ tie my %unrateable_opts, 'Tie::IxHash', skip_max_callers use_duration 411_rewrite - output_format usage_mandate summarize_usage usage_section + output_format + selfservice_format selfservice_inbound_format + usage_mandate summarize_usage usage_section bill_every_call bill_inactive_svcs count_available_phones suspend_bill ) diff --git a/FS/FS/pay_batch/BoM.pm b/FS/FS/pay_batch/BoM.pm index 719b504e5..a3708d477 100644 --- a/FS/FS/pay_batch/BoM.pm +++ b/FS/FS/pay_batch/BoM.pm @@ -31,13 +31,13 @@ $name = 'BoM'; }, header => sub { my $pay_batch = shift; - sprintf( "A%10s%04u%06u%05u%54s\n", #80 + sprintf( "A%10s%04u%06u%05u%53s\n", #80 $origid, $pay_batch->batchnum, jdate($pay_batch->download), $datacenter, "") . - sprintf( "XD%03u%06u%-15s%-30s%09u%-12s \n", #80 + sprintf( "XD%03u%06u%-15s%-30s%09u%-12s ", #80 $typecode, jdate($pay_batch->download), $shortname, @@ -48,7 +48,7 @@ $name = 'BoM'; row => sub { my ($cust_pay_batch, $pay_batch) = @_; my ($account, $aba) = split('@', $cust_pay_batch->payinfo); - sprintf( "D%010.0f%09u%-12s%-29s%-19s\n", #80 + sprintf( "D%010.0f%09u%-12s%-29s%-18s ", #80 $cust_pay_batch->amount * 100, $aba, $account, @@ -58,8 +58,8 @@ $name = 'BoM'; }, footer => sub { my ($pay_batch, $batchcount, $batchtotal) = @_; - sprintf( "YD%08u%014.0f%56s\n", $batchcount, $batchtotal*100, ""). #80 - sprintf( "Z%014u%04u%014u%05u%42s\n", #80 now + sprintf( "YD%08u%014.0f%55s\n", $batchcount, $batchtotal*100, ""). #80 + sprintf( "Z%014u%05u%014u%05u%40s", #80 now $batchtotal*100, $batchcount, "0", "0", ""); }, ); diff --git a/FS/FS/rate.pm b/FS/FS/rate.pm index a2511cf99..49ac938fd 100644 --- a/FS/FS/rate.pm +++ b/FS/FS/rate.pm @@ -308,17 +308,28 @@ sub dest_detail { #find a rate prefix, first look at most specific, then fewer digits, # finally trying the country code only my $rate_prefix = ''; - for my $len ( reverse(1..10) ) { - $rate_prefix = qsearchs('rate_prefix', { + $rate_prefix = qsearchs({ + 'table' => 'rate_prefix', + 'addl_from' => ' JOIN rate_region USING (regionnum)', + 'hashref' => { + 'countrycode' => $countrycode, + 'npa' => $phonenum, + }, + 'extra_sql' => ' AND exact_match = \'Y\'' + }); + if (!$rate_prefix) { + for my $len ( reverse(1..10) ) { + $rate_prefix = qsearchs('rate_prefix', { + 'countrycode' => $countrycode, + #'npa' => { op=> 'LIKE', value=> substr($number, 0, $len) } + 'npa' => substr($phonenum, 0, $len), + } ) and last; + } + $rate_prefix ||= qsearchs('rate_prefix', { 'countrycode' => $countrycode, - #'npa' => { op=> 'LIKE', value=> substr($number, 0, $len) } - 'npa' => substr($phonenum, 0, $len), - } ) and last; + 'npa' => '', + }); } - $rate_prefix ||= qsearchs('rate_prefix', { - 'countrycode' => $countrycode, - 'npa' => '', - }); return '' unless $rate_prefix; diff --git a/FS/FS/rate_region.pm b/FS/FS/rate_region.pm index f4a0ab196..d42fdb41e 100644 --- a/FS/FS/rate_region.pm +++ b/FS/FS/rate_region.pm @@ -36,7 +36,10 @@ inherits from FS::Record. The following fields are currently supported: =item regionnum - primary key -=item regionname +=item regionname - name of the region + +=item exact_match - 'Y' if "prefixes" in this region really represent +complete phone numbers. Null if they represent prefixes (the usual case). =back @@ -233,6 +236,7 @@ sub check { my $error = $self->ut_numbern('regionnum') || $self->ut_text('regionname') + || $self->ut_flag('exact_match') ; return $error if $error; diff --git a/FS/FS/svc_phone.pm b/FS/FS/svc_phone.pm index bf610c62b..f28002cc4 100644 --- a/FS/FS/svc_phone.pm +++ b/FS/FS/svc_phone.pm @@ -688,6 +688,8 @@ with the chosen prefix. =item disable_src => 1: Only match on "charged_party", not "src". +=item nonzero: Only return CDRs where duration > 0. + =item by_svcnum: not supported for svc_phone =item billsec_sum: Instead of returning all of the CDRs, return a single @@ -755,6 +757,9 @@ sub psearch_cdrs { if ( $options{'end'} ) { push @where, 'startdate < '. $options{'end'}; } + if ( $options{'nonzero'} ) { + push @where, 'duration > 0'; + } my $extra_sql = ( keys(%hash) ? ' AND ' : ' WHERE ' ). join(' AND ', @where ); @@ -781,6 +786,30 @@ sub get_cdrs { qsearch ( $psearch->{query} ) } +=item sum_cdrs + +Takes the same options as psearch_cdrs, but returns a single row containing +"count" (the number of CDRs) and the sums of the following fields: duration, +billsec, rated_price, rated_seconds, rated_minutes. + +Note that if any calls are not rated, their rated_* fields will be null. +If you want to use those fields, pass the 'status' option to limit to +calls that have been rated. This is intentional; please don't "fix" it. + +=cut + +sub sum_cdrs { + my $self = shift; + my $psearch = $self->psearch_cdrs(@_); + $psearch->{query}->{'select'} = join(',', + 'COUNT(*) AS count', + map { "SUM($_) AS $_" } + qw(duration billsec rated_price rated_seconds rated_minutes) + ); + # hack + $psearch->{query}->{'extra_sql'} =~ s/ ORDER BY.*$//; + qsearchs ( $psearch->{query} ); +} =back diff --git a/FS/bin/freeside-cdrrewrited b/FS/bin/freeside-cdrrewrited index f2c3926fb..16f931fbf 100644 --- a/FS/bin/freeside-cdrrewrited +++ b/FS/bin/freeside-cdrrewrited @@ -30,9 +30,9 @@ die "not running; cdr-asterisk_forward_rewrite, cdr-charged_party_rewrite ". #-- -my %accountcode_unmatch = (); -my $accountcode_retry = 4 * 60 * 60; # 4 hours -my $accountcode_giveup = 4 * 24 * 60 * 60; # 4 days +my %sessionnum_unmatch = (); +my $sessionnum_retry = 4 * 60 * 60; # 4 hours +my $sessionnum_giveup = 4 * 24 * 60 * 60; # 4 days my %cdr_type = map { lc($_->cdrtypename) => $_->cdrtypenum } qsearch('cdr_type',{}); @@ -45,8 +45,8 @@ while (1) { # instead of just doing this search like normal CDRs #hmm :/ - my @recent = grep { ($accountcode_unmatch{$_} + $accountcode_retry) > time } - keys %accountcode_unmatch; + my @recent = grep { ($sessionnum_unmatch{$_} + $sessionnum_retry) > time } + keys %sessionnum_unmatch; my $extra_sql = scalar(@recent) ? ' AND acctid NOT IN ('. join(',', @recent). ') ' : ''; @@ -136,45 +136,62 @@ while (1) { } - if ( $conf->exists('cdr-taqua-accountcode_rewrite') - && $cdr->lastapp eq 'acctcode' && $cdr->cdrtypenum == 1 + if ( $cdr->cdrtypenum == 1 + and $cdr->lastapp + and ( + $conf->exists('cdr-taqua-accountcode_rewrite') or + $conf->exists('cdr-taqua-callerid_rewrite') ) ) { #find the matching CDR - my $primary = qsearchs('cdr', { - 'sessionnum' => $cdr->sessionnum, - 'src' => $cdr->subscriber, - #'accountcode' => '', - }); + my %search = ( 'sessionnum' => $cdr->sessionnum ); + if ( $cdr->lastapp eq 'acctcode' ) { + $search{'src'} = $cdr->subscriber; + } elsif ( $cdr->lastapp eq 'CallerId' ) { + $search{'dst'} = $cdr->subscriber; + } + my $primary = qsearchs('cdr', \%search); unless ( $primary ) { my $cantfind = "can't find primary CDR with session ". $cdr->sessionnum. ", src ". $cdr->subscriber; - if ( $cdr->calldate_unix + $accountcode_giveup < time ) { + if ( $cdr->calldate_unix + $sessionnum_giveup < time ) { warn "ERROR: $cantfind; giving up\n"; - push @status, 'taqua-accountcode-NOTFOUND'; + push @status, 'taqua-sessionnum-NOTFOUND'; $cdr->status('done'); #so it doesn't try to rate - delete $accountcode_unmatch{$cdr->acctid}; #so it doesn't suck mem + delete $sessionnum_unmatch{$cdr->acctid}; #so it doesn't suck mem } else { warn "WARNING: $cantfind; will keep trying\n"; - $accountcode_unmatch{$cdr->acctid} = time; + $sessionnum_unmatch{$cdr->acctid} = time; next; } } else { - $primary->accountcode( $cdr->lastdata ); + if ( $cdr->lastapp eq 'acctcode' ) { + # lastdata contains the dialed account code + $primary->accountcode( $cdr->lastdata ); + push @status, 'taqua-accountcode'; + } elsif ( $cdr->lastapp eq 'CallerId' ) { + # lastdata contains "allowed" or "restricted" + # or case variants thereof + if ( lc($cdr->lastdata) eq 'restricted' ) { + $primary->clid( 'PRIVATE' ); + } + push @status, 'taqua-callerid'; + } else { + warn "unknown Taqua service name: ".$cdr->lastapp."\n"; + } #$primary->freesiderewritestatus( 'taqua-accountcode-primary' ); - my $error = $primary->replace; + my $error = $primary->replace if $primary->modified; if ( $error ) { warn "WARNING: error rewriting primary CDR (will retry): $error\n"; next; } $skip{$primary->acctid} = 1; - push @status, 'taqua-accountcode'; $cdr->status('done'); #so it doesn't try to rate } @@ -214,7 +231,10 @@ sub _shouldrun { $conf->exists('cdr-asterisk_forward_rewrite') || $conf->exists('cdr-asterisk_australia_rewrite') || $conf->exists('cdr-charged_party_rewrite') - || $conf->exists('cdr-taqua-accountcode_rewrite'); + || $conf->exists('cdr-taqua-accountcode_rewrite') + || $conf->exists('cdr-taqua-callerid_rewrite') + || 0 + ; } sub usage { |