From 81a993ab0d0f15d896144f60cbf9477fdf693f76 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Fri, 24 Feb 2012 08:45:46 -0800 Subject: [PATCH] CDR rewriting and included-calls feature, #16271 --- FS/FS/Conf.pm | 7 +++++ FS/FS/detail_format.pm | 6 +++- FS/FS/detail_format/sum_count.pm | 3 +- FS/FS/detail_format/sum_duration.pm | 3 +- FS/FS/detail_format/sum_duration_prefix.pm | 3 +- FS/FS/part_pkg/voip_cdr.pm | 19 ++++++++++-- FS/bin/freeside-cdrrewrited | 50 ++++++++++++++++++++++++++++++ 7 files changed, 84 insertions(+), 7 deletions(-) diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm index 4393dcfdd..38a689448 100644 --- a/FS/FS/Conf.pm +++ b/FS/FS/Conf.pm @@ -4258,6 +4258,13 @@ and customer address. Include units.', }, { + 'key' => 'cdr-asterisk_australia_rewrite', + 'section' => 'telephony', + 'description' => 'For Asterisk CDRs, assign CDR type numbers based on Australian conventions.', + 'type' => 'checkbox', + }, + + { 'key' => 'cust_pkg-show_autosuspend', 'section' => 'UI', 'description' => 'Show package auto-suspend dates. Use with caution for now; can slow down customer view for large insallations.', diff --git a/FS/FS/detail_format.pm b/FS/FS/detail_format.pm index 144aaa75f..af97f36b4 100644 --- a/FS/FS/detail_format.pm +++ b/FS/FS/detail_format.pm @@ -171,8 +171,11 @@ sub single_detail { die "$me error combining ".$self->csv->error_input."\n" if !$status; + my $rated_price = $cdr->rated_price; + $rated_price = 0 if $cdr->freesidestatus eq 'no-charge'; + FS::cust_bill_pkg_detail->new( { - 'amount' => $cdr->rated_price, + 'amount' => $rated_price, 'classnum' => $cdr->rated_classnum, 'duration' => $cdr->rated_seconds, 'regionname' => $cdr->rated_regionname, @@ -250,6 +253,7 @@ sub price { my $cdr = shift; my $object = $self->{inbound} ? $cdr->cdr_termination(1) : $cdr; my $price = $object->rated_price if $object; + $price = '0.00' if $object->freesidestatus eq 'no-charge'; length($price) ? $self->money_char . $price : ''; } diff --git a/FS/FS/detail_format/sum_count.pm b/FS/FS/detail_format/sum_count.pm index 5cf87c7f4..c40fcb8fe 100644 --- a/FS/FS/detail_format/sum_count.pm +++ b/FS/FS/detail_format/sum_count.pm @@ -31,7 +31,8 @@ sub append { my $subtotal = ($svcnums->{$svcnum} ||= { count => 0, duration => 0, amount => 0 }); $subtotal->{count}++; - $subtotal->{amount} += $object->rated_price; + $subtotal->{amount} += $object->rated_price + if $object->freesidestatus ne 'no-charge'; } } diff --git a/FS/FS/detail_format/sum_duration.pm b/FS/FS/detail_format/sum_duration.pm index 4af7f0a21..1b967b407 100644 --- a/FS/FS/detail_format/sum_duration.pm +++ b/FS/FS/detail_format/sum_duration.pm @@ -32,7 +32,8 @@ sub append { { count => 0, duration => 0, amount => 0 }); $subtotal->{count}++; $subtotal->{duration} += $object->rated_seconds; - $subtotal->{amount} += $object->rated_price; + $subtotal->{amount} += $object->rated_price + if $object->freesidestatus ne 'no-charge'; } } diff --git a/FS/FS/detail_format/sum_duration_prefix.pm b/FS/FS/detail_format/sum_duration_prefix.pm index 19b6648f8..d70ad0e5a 100644 --- a/FS/FS/detail_format/sum_duration_prefix.pm +++ b/FS/FS/detail_format/sum_duration_prefix.pm @@ -47,7 +47,8 @@ sub append { # "' in CDR #".$cdr->acctid."\n"; $subtotal->{count}++; $subtotal->{duration} += $object->rated_seconds; - $subtotal->{amount} += $object->rated_price; + $subtotal->{amount} += $object->rated_price + if $object->freesidestatus ne 'no-charge'; } } diff --git a/FS/FS/part_pkg/voip_cdr.pm b/FS/FS/part_pkg/voip_cdr.pm index 00724012a..3c456dc02 100644 --- a/FS/FS/part_pkg/voip_cdr.pm +++ b/FS/FS/part_pkg/voip_cdr.pm @@ -100,6 +100,8 @@ tie my %unrateable_opts, 'Tie::IxHash', 'empty_label' => '', }, + 'calls_included' => { 'name' => 'Number of calls included at no usage charge', }, + 'min_included' => { 'name' => 'Minutes included when using the "single price per minute" rating method or when using the "prefix" rating method ("region group" billing)', }, @@ -267,6 +269,7 @@ tie my %unrateable_opts, 'Tie::IxHash', qw( cdr_svc_method rating_method ratenum intrastate_ratenum + calls_included min_charge min_included sec_granularity ignore_unrateable default_prefix @@ -339,6 +342,7 @@ sub calc_usage { my $charges = 0; my $included_min = $self->option('min_included', 1) || 0; #single price rating + my $included_calls = $self->option('calls_included', 1) || 0; my $cdr_svc_method = $self->option('cdr_svc_method',1)||'svc_phone.phonenum'; my $rating_method = $self->option('rating_method') || 'prefix'; @@ -410,11 +414,20 @@ sub calc_usage { foreach my $cdr ( $svc_x->get_cdrs( %options ) ) { + my $error; # at this point we officially Do Not Care about the rating method - $charges += $cdr->rated_price; - $formatter->append($cdr); - my $error = $cdr->set_status('done'); + if ( $included_calls > 0 ) { + $included_calls--; + #$charges += 0, obviously + #but don't set the rated price to zero--there should be a record + $error = $cdr->set_status('no-charge'); + } + else { + $charges += $cdr->rated_price; + $error = $cdr->set_status('done'); + } die $error if $error; + $formatter->append($cdr); } } diff --git a/FS/bin/freeside-cdrrewrited b/FS/bin/freeside-cdrrewrited index 846b0b976..f2c3926fb 100644 --- a/FS/bin/freeside-cdrrewrited +++ b/FS/bin/freeside-cdrrewrited @@ -34,6 +34,9 @@ my %accountcode_unmatch = (); my $accountcode_retry = 4 * 60 * 60; # 4 hours my $accountcode_giveup = 4 * 24 * 60 * 60; # 4 days +my %cdr_type = map { lc($_->cdrtypename) => $_->cdrtypenum } + qsearch('cdr_type',{}); + while (1) { #hmm... don't want to do an expensive search with an ever-growing bunch @@ -50,6 +53,8 @@ while (1) { my $found = 0; my %skip = (); + my %warning = (); + foreach my $cdr ( qsearch( { 'table' => 'cdr', @@ -85,6 +90,45 @@ while (1) { } + # XXX weird special case stuff--can we modularize this somehow? + # reference RT#16271 + if ( $conf->exists('cdr-asterisk_australia_rewrite') and + $cdr->disposition eq 'ANSWERED' ) { + my $dst = $cdr->dst; + my $type; + if ( $dst =~ /^0?(12|13|1800|1900|0055)/ ) { + # toll free or smart numbers, any length + $type = 'tollfree'; + $cdr->charged_party($dst); + } + elsif ( $dst =~ /^(11|0011)/ ) { + # will be followed by country code + $type = 'international'; + $dst =~ s/^$1/0011/; #standardize + $cdr->dst($dst); + } + elsif ( length($dst) == 10 and$dst =~ /^04/ ) { + $type = 'mobile'; + } + elsif ( length($dst) == 10 and $dst =~ /^02|03|07|08/ ) { + $type = 'domestic'; + } + elsif ( length($dst) == 8 ) { + # local call, no area code + $type = 'domestic'; + } + else { + $type = 'other'; + } + if ( $type and exists($cdr_type{$type}) ) { + $cdr->cdrtypenum($cdr_type{$type}); + push @status, 'asterisk_australia'; + } + else { + $warning{"no CDR type defined for $type calls"}++; + } + } + if ( $conf->exists('cdr-charged_party_rewrite') && ! $cdr->charged_party ) { $cdr->set_charged_party; @@ -153,6 +197,11 @@ while (1) { } + foreach (sort keys %warning) { + warn "WARNING: $_ (x $warning{$_})\n"; + } + %warning = (); + myexit() if sigterm() || sigint(); #sleep 1 unless $found; sleep 5 unless $found; @@ -163,6 +212,7 @@ while (1) { 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'); } -- 2.11.0