diff options
| author | mark <mark> | 2011-02-11 23:59:29 +0000 | 
|---|---|---|
| committer | mark <mark> | 2011-02-11 23:59:29 +0000 | 
| commit | 6a10d16ff4e806357abab206254aa38c80a749d3 (patch) | |
| tree | 94dfb9705ba9d5aa8b3b0d1d96be6ba460115404 /FS | |
| parent | ca2b8a8c99585a4619eb657f2c7fca12a7304249 (diff) | |
rate selection by CDR type, RT#10991
Diffstat (limited to 'FS')
| -rw-r--r-- | FS/FS/Schema.pm | 1 | ||||
| -rw-r--r-- | FS/FS/cdr_type.pm | 4 | ||||
| -rw-r--r-- | FS/FS/part_pkg/voip_cdr.pm | 11 | ||||
| -rw-r--r-- | FS/FS/rate.pm | 80 | ||||
| -rw-r--r-- | FS/FS/rate_detail.pm | 16 | 
5 files changed, 74 insertions, 38 deletions
| diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm index 71403b428..040f6df21 100644 --- a/FS/FS/Schema.pm +++ b/FS/FS/Schema.pm @@ -2489,6 +2489,7 @@ sub tables_hashref {          'sec_granularity', 'int',     '',     '', '', '',           'ratetimenum',     'int', 'NULL',     '', '', '',          'classnum',        'int', 'NULL',     '', '', '',  +        'cdrtypenum',      'int', 'NULL',     '', '', '',        ],        'primary_key' => 'ratedetailnum',        'unique'      => [ [ 'ratenum', 'orig_regionnum', 'dest_regionnum' ] ], diff --git a/FS/FS/cdr_type.pm b/FS/FS/cdr_type.pm index e258bf878..d16b85cf6 100644 --- a/FS/FS/cdr_type.pm +++ b/FS/FS/cdr_type.pm @@ -34,7 +34,7 @@ FS::Record.  The following fields are currently supported:  =item cdrtypenum - primary key -=item typename - CDR type name +=item cdrtypename - CDR type name  =back @@ -98,7 +98,7 @@ sub check {    my $error =       $self->ut_numbern('cdrtypenum') -    || $self->ut_text('typename') +    || $self->ut_text('cdrtypename')    ;    return $error if $error; diff --git a/FS/FS/part_pkg/voip_cdr.pm b/FS/FS/part_pkg/voip_cdr.pm index fea38c1d0..800f92924 100644 --- a/FS/FS/part_pkg/voip_cdr.pm +++ b/FS/FS/part_pkg/voip_cdr.pm @@ -333,7 +333,7 @@ sub calc_usage {    my $disable_tollfree  = $self->option('disable_tollfree');    my $ignore_unrateable = $self->option('ignore_unrateable', 'Hush!');    my $use_duration      = $self->option('use_duration'); -  my $region_group	= ($rating_method eq 'prefix' && $self->option('min_included') > 0); +  my $region_group	= ($rating_method eq 'prefix' && ($self->option('min_included') || 0) > 0);    my $region_group_included_min = $region_group ? $self->option('min_included') : 0;    my $output_format     = $self->option('output_format', 'Hush!') @@ -502,6 +502,7 @@ sub calc_usage {            $rate_detail = $rate->dest_detail({ 'countrycode' => $countrycode,                                                'phonenum'    => $number,                                                'weektime'    => $weektime, +                                              'cdrtypenum'  => $cdr->cdrtypenum,                                              });            if ( $rate_detail ) { @@ -568,10 +569,7 @@ sub calc_usage {            if $seconds      # don't granular-ize 0 billsec calls (bills them)            && $granularity  # 0 is per call            && $seconds % $granularity; -        my $minutes = $seconds / 60; -        # XXX config? -        #$charge = sprintf('%.2f', ( $self->option('min_charge') * $minutes ) -                                  #+ 0.00000001 ); #so 1.005 rounds to 1.01 +        my $minutes = $granularity ? ($seconds / 60) : 1;          $charge = sprintf('%.4f', ( $self->option('min_charge') * $minutes )                                    + 0.0000000001 ); #so 1.00005 rounds to 1.0001 @@ -692,7 +690,8 @@ sub calc_usage {              # choose next rate_detail              $rate_detail = $rate->dest_detail({ 'countrycode' => $countrycode,                                                  'phonenum'    => $number, -                                                'weektime'    => $etime }) +                                                'weektime'    => $etime, +                                                'cdrtypenum'  => $cdr->cdrtypenum })                      if($seconds_left);              # we have now moved forward to $etime              $weektime = $etime; diff --git a/FS/FS/rate.pm b/FS/FS/rate.pm index f30e4c772..02d8250eb 100644 --- a/FS/FS/rate.pm +++ b/FS/FS/rate.pm @@ -276,25 +276,34 @@ specificed destination, or the empty string if no rate can be found for  the given destination.  Destination can be specified as an FS::rate_detail object or regionnum -(see L<FS::rate_detail>), or as a hashref with two keys: I<countrycode> -and I<phonenum>. +(see L<FS::rate_detail>), or as a hashref containing the following keys: -An optional third key, I<weektime>, will return a timed rate (one with  -a non-null I<ratetimenum>) if one exists for a call at that time.  If  -no matching timed rate exists, the non-timed rate will be returned. +=over 2 + +=item I<countrycode> - required. + +=item I<phonenum> - required. + +=item I<weektime> - optional.  Specifies a time in seconds from the start  +of the week, and will return a timed rate (one with a non-null I<ratetimenum>) +if one exists at that time.  If not, returns a non-timed rate. + +=item I<cdrtypenum> - optional.  Specifies a value for the cdrtypenum  +field, and will return a rate matching that, if one exists.  If not, returns  +a rate with null cdrtypenum.  =cut  sub dest_detail {    my $self = shift; -  my $regionnum; -  my $weektime; +  my( $regionnum, $weektime, $cdrtypenum );    if ( ref($_[0]) eq 'HASH' ) {      my $countrycode = $_[0]->{'countrycode'};      my $phonenum    = $_[0]->{'phonenum'};      $weektime       = $_[0]->{'weektime'}; +    $cdrtypenum     = $_[0]->{'cdrtypenum'} || '';      #find a rate prefix, first look at most specific, then fewer digits,      # finally trying the country code only @@ -315,36 +324,47 @@ sub dest_detail {      $regionnum = $rate_prefix->regionnum; -    #$rate_region = $rate_prefix->rate_region; -    } else {      $regionnum = ref($_[0]) ? shift->regionnum : shift;    } -   -  if(!defined($weektime)) { -    return qsearchs( 'rate_detail',  -                            { 'ratenum'        => $self->ratenum, -                              'dest_regionnum' => $regionnum, -                              'ratetimenum'    => '', -                            } ); + +  my %hash = ( +    'ratenum'         => $self->ratenum, +    'dest_regionnum'  => $regionnum, +  ); + +  # find all rates matching ratenum, regionnum, cdrtypenum +  my @details = qsearch( 'rate_detail', {  +      %hash, +      'cdrtypenum' => $cdrtypenum +    }); +  # find all rates maching ratenum, regionnum and null cdrtypenum +  if ( !@details and $cdrtypenum ) { +    @details = qsearch( 'rate_detail', { +        %hash, +        'cdrtypenum' => '' +      });    } -  else { -    my @details = grep { my $rate_time = $_->rate_time; -                            $rate_time && $rate_time->contains($weektime) } -                       qsearch( 'rate_detail', -                                    { 'ratenum'        => $self->ratenum, -                                      'dest_regionnum' => $regionnum, } ); -    if(!@details) { -      # this may change at some point -      return $self->dest_detail($regionnum); +  # find one of those matching weektime +  if ( defined($weektime) ) { +    my @exact = grep {  +      my $rate_time = $_->rate_time; +      $rate_time && $rate_time->contains($weektime) +    } @details; +    if ( @exact == 1 ) { +      return $exact[0];      } -    elsif(@details == 1) { -      return $details[0]; -    } -    else { -      die "overlapping rate_detail times (region $regionnum, time $weektime)\n"; +    elsif ( @exact > 1 ) { +      die "overlapping rate_detail times (region $regionnum, time $weektime)\n"      } +    # else @exact == 0 +  } +  # if not found or there is no weektime, find one matching null weektime +  foreach (@details) { +    return $_ if $_->ratetimenum eq '';    } +  # found nothing +  return;  }  =item rate_detail diff --git a/FS/FS/rate_detail.pm b/FS/FS/rate_detail.pm index 7b9045205..918134a3a 100644 --- a/FS/FS/rate_detail.pm +++ b/FS/FS/rate_detail.pm @@ -57,6 +57,8 @@ inherits from FS::Record.  The following fields are currently supported:  =item ratetimenum - rating time period (see L<FS::rate_time) if any +=item cdrtypenum - CDR type (see L<FS::cdr_type>) if any for this rate +  =back  =head1 METHODS @@ -234,6 +236,20 @@ sub classname {    $usage_class ? $usage_class->classname : '';  } +=item cdrtypename + +Returns the name of the CDR type (see L<FS::cdr_type) associated with this  +rate, if there is one.  If not, returns the cdrtypenum itself.  This will  +only return an empty string if cdrtypenum is NULL. + +=cut + +sub cdrtypename { +  my $self = shift; +  my $cdrtypenum = $self->cdrtypenum or return ''; +  my $cdr_type = qsearchs('cdr_type', { cdrtypenum => $cdrtypenum }); +  return $cdr_type ? $cdr_type->cdrtypename : $cdrtypenum; +}  =back | 
