package FS::part_pkg::voip_cdr;
+use base qw( FS::part_pkg::recur_Common );
use strict;
-use base qw( FS::part_pkg::recur_Common );
use vars qw( $DEBUG %info );
-use Date::Format;
+use List::Util qw(first min);
use Tie::IxHash;
+use Date::Format;
+use Text::CSV_XS;
use FS::Conf;
use FS::Record qw(qsearchs qsearch);
use FS::cdr;
use FS::rate_prefix;
use FS::rate_detail;
-use List::Util qw(first min);
-
-
$DEBUG = 0;
tie my %cdr_svc_method, 'Tie::IxHash',
qw(
cdr_svc_method
rating_method ratenum intrastate_ratenum
- min_charge min_included
- sec_granularity
+ min_charge min_included sec_granularity
ignore_unrateable
default_prefix
disable_src
my $spool_cdr = $cust_pkg->cust_main->spool_cdr;
- my %included_min = ();
+ my %included_min = (); #region groups w/prefix rating
+
+ my $included_min = $self->option('min_included', 1) || 0; #single price rating
my $charges = 0;
#for check_chargable, so we don't keep looking up options inside the loop
my %opt_cache = ();
- eval "use Text::CSV_XS;";
- die $@ if $@;
my $csv = new Text::CSV_XS;
my($svc_table, $svc_field) = split('\.', $cdr_svc_method);
my $seconds = '';
my $weektime = '';
my $regionname = '';
+ my $ratename = '';
my $classnum = '';
my $countrycode;
my $number;
? $cust_pkg->part_pkg->option('accountcode_tollfree_ratenum')
: '';
- my $intrastate_ratenum = $cust_pkg->part_pkg->option('accountcode_tollfree_ratenum');
+ my $intrastate_ratenum = $cust_pkg->part_pkg->option('intrastate_ratenum');
if ( $intrastate_ratenum && !$cdr->is_tollfree ) {
+ $ratename = 'Interstate'; #until proven otherwise
# this is relatively easy only because:
# -assume all numbers are valid NANP numbers NOT in a fully-qualified format
# -disregard toll-free
$srcprefix = qsearchs('rate_prefix', { 'countrycode' => '1',
'npa' => $1,
}) || '';
- $eff_ratenum = $intrastate_ratenum if ($srcprefix && $dstprefix
+ if ($srcprefix && $dstprefix
&& $srcprefix->state && $dstprefix->state
- && $srcprefix->state eq $dstprefix->state);
+ && $srcprefix->state eq $dstprefix->state) {
+ $eff_ratenum = $intrastate_ratenum;
+ $ratename = 'Intrastate'; # XXX possibly just use the ratename?
+ }
}
$eff_ratenum ||= $ratenum;
&& $granularity # 0 is per call
&& $seconds % $granularity;
my $minutes = $granularity ? ($seconds / 60) : 1;
- $charge = sprintf('%.4f', ( $self->option('min_charge') * $minutes )
+
+ my $charge_min = $minutes;
+
+ $included_min -= $minutes;
+ if ( $included_min > 0 ) {
+ $charge_min = 0;
+ } else {
+ $charge_min = 0 - $included_min;
+ $included_min = 0;
+ }
+
+ $charge = sprintf('%.4f', ( $self->option('min_charge') * $charge_min )
+ 0.0000000001 ); #so 1.00005 rounds to 1.0001
warn "Incrementing \$charges by $charge. Now $charges\n" if $DEBUG;
);
}
} #if(there is a rate_detail)
-
#if ( $charge > 0 ) {
# generate a detail record for every call; filter out $charge = 0
regionname => $regionname,
};
}
+ $call_details->{'ratename'} = $ratename;
+
push @invoice_details_sort, [ $call_details, $cdr->calldate_unix ];
#} $charge > 0
my $self = shift;
my $svc_x = shift;
my $invoice_details = shift || [];
- my $count = scalar(@$invoice_details);
- return () if !$count;
- my $sum_detail = {
- amount => 0,
- format => 'C',
- classnum => '', #XXX
- duration => 0,
- phonenum => $svc_x->phonenum,
- accountcode => '', #XXX
- startdate => '', #XXX
- regionnam => '',
- };
+ return () if !@$invoice_details;
+ my $details_by_rate = {};
# combine the entire set of CDRs
foreach ( @$invoice_details ) {
- $sum_detail->{amount} += $_->[0]{amount};
- $sum_detail->{duration} += $_->[0]{duration};
+ my $d = $_->[0];
+ my $sum = $details_by_rate->{ $d->{ratename} } ||= {
+ amount => 0,
+ format => 'C',
+ classnum => '', #XXX
+ duration => 0,
+ phonenum => $svc_x->phonenum,
+ accountcode => '', #XXX
+ startdate => '', #XXX
+ regionname => '',
+ count => 0,
+ };
+ $sum->{amount} += $d->{amount};
+ $sum->{duration} += $d->{duration};
+ $sum->{count}++;
}
- my $total_cdr = FS::cdr->new({
- 'billsec' => $sum_detail->{duration},
- 'src' => $sum_detail->{phonenum},
- });
- $sum_detail->{detail} = $total_cdr->downstream_csv(
- format => $self->option('output_format'),
- seconds => $sum_detail->{duration},
- charge => sprintf('%.2f',$sum_detail->{amount}),
- phonenum => $sum_detail->{phonenum},
- count => $count,
- );
- return $sum_detail;
+ my @details;
+ foreach my $ratename ( sort keys(%$details_by_rate) ) {
+ my $sum = $details_by_rate->{$ratename};
+ next if $sum->{count} == 0;
+ my $total_cdr = FS::cdr->new({
+ 'billsec' => $sum->{duration},
+ 'src' => $sum->{phonenum},
+ });
+ $sum->{detail} = $total_cdr->downstream_csv(
+ format => $self->option('output_format'),
+ seconds => $sum->{duration},
+ charge => sprintf('%.2f',$sum->{amount}),
+ ratename => $ratename,
+ phonenum => $sum->{phonenum},
+ count => $sum->{count},
+ );
+ push @details, $sum;
+ }
+ @details;
}
# and whether cust_bill should show a detail line for the service label