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 | |
| parent | ca2b8a8c99585a4619eb657f2c7fca12a7304249 (diff) | |
rate selection by CDR type, RT#10991
| -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 | ||||
| -rw-r--r-- | httemplate/browse/elements/browse.html | 2 | ||||
| -rw-r--r-- | httemplate/browse/rate.cgi | 7 | ||||
| -rw-r--r-- | httemplate/browse/rate_detail.html | 40 | ||||
| -rw-r--r-- | httemplate/browse/rate_region.html | 2 | ||||
| -rw-r--r-- | httemplate/edit/cdr_type.cgi | 31 | ||||
| -rw-r--r-- | httemplate/edit/process/cdr_type.cgi | 42 | ||||
| -rw-r--r-- | httemplate/edit/rate.cgi | 32 | ||||
| -rw-r--r-- | httemplate/edit/rate_detail.html | 4 | ||||
| -rw-r--r-- | httemplate/edit/rate_region.cgi | 31 | ||||
| -rw-r--r-- | httemplate/elements/auto-table.html | 9 | ||||
| -rw-r--r-- | httemplate/elements/select-cdr_type.html | 11 | 
16 files changed, 226 insertions, 97 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 diff --git a/httemplate/browse/elements/browse.html b/httemplate/browse/elements/browse.html index 513c2c4e9..9099d6538 100644 --- a/httemplate/browse/elements/browse.html +++ b/httemplate/browse/elements/browse.html @@ -1,5 +1,5 @@  <% include( '/search/elements/search.html', -               'disable_download'  => 1, +               'really_disable_download'  => 1,                 'disable_nonefound' => 1,                 @_,             ) diff --git a/httemplate/browse/rate.cgi b/httemplate/browse/rate.cgi index c6cfec074..0c425a5d1 100644 --- a/httemplate/browse/rate.cgi +++ b/httemplate/browse/rate.cgi @@ -4,6 +4,8 @@                                     $p.'browse/rate_region.html',                                   'Time Periods' =>                                     $p.'browse/rate_time.html', +                                 'CDR Types' => +                                   $p.'edit/cdr_type.cgi',                                 ],                'html_init'   => $html_init,                'name'        => 'rate plans', @@ -15,6 +17,7 @@                'header'      => [ '#',       'Rate plan', 'Rates'    ],                'fields'      => [ 'ratenum', 'ratename',  $rates_sub ],                'links'       => [ $link,     $link,       ''         ], +              'really_disable_download' => 1            )  %>  <%once> @@ -27,7 +30,7 @@ my $rates_sub = sub {    my $rate = shift;    my $ratenum = $rate->ratenum; -  qq( <FORM METHOD="GET" ACTION="${p}browse/rate_detail.html"> +  qq( <FORM METHOD="GET" ACTION="${p}edit/rate.cgi">          <INPUT TYPE="hidden" NAME="ratenum" VALUE="$ratenum">          <SELECT NAME="countrycode" onChange="this.form.submit();">            <OPTION SELECTED>Select Country Code @@ -55,7 +58,7 @@ my $html_init =  my $count_query = 'SELECT COUNT(*) FROM rate'; -my $link = [ $p.'edit/rate.cgi?', 'ratenum' ]; +my $link = [ $p.'edit/rate.cgi?ratenum=', 'ratenum' ];  </%once>  <%init> diff --git a/httemplate/browse/rate_detail.html b/httemplate/browse/rate_detail.html deleted file mode 100644 index aef550513..000000000 --- a/httemplate/browse/rate_detail.html +++ /dev/null @@ -1,40 +0,0 @@ -<% include('/elements/init_overlib.html') %> -<% include('/elements/header.html',$title) %> -<% include('/elements/menubar.html',@menubar) %> -<% include('/edit/elements/rate_detail.html', -    'ratenum' => $ratenum, -    'countrycode' => $countrycode, -) %> -<% include('/elements/footer.html') %> - -<%once> - -my $conf = new FS::Conf; -my $money_char = $conf->config('money_char') || '$'; - -my @menubar = ( 'Rate plans' => $p.'browse/rate.cgi', -                'Regions and Prefixes' => $p.'browse/rate_region.html', -                'Time Periods' => $p.'browse/rate_time.html', -                ); - -</%once> -<%init> - -die "access denied" -  unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); - -$cgi->param('ratenum') =~ /^(\d+)$/ or die "unparsable ratenum"; -my $ratenum = $1; -my $rate = qsearchs('rate', { 'ratenum' => $ratenum } ) -  or die "unknown ratenum $ratenum"; -my $ratename = $rate->ratename; -my $title = "$ratename rates"; - -my $where; -my $countrycode = ''; -if ( $cgi->param('countrycode') =~ /^(\d+)$/ ) {  -  $countrycode = $1; -  $title .= " for +$countrycode"; -} - -</%init> diff --git a/httemplate/browse/rate_region.html b/httemplate/browse/rate_region.html index b7d9589d0..b958894cb 100644 --- a/httemplate/browse/rate_region.html +++ b/httemplate/browse/rate_region.html @@ -23,7 +23,7 @@  my $edit_url = $p.'edit/rate_region.cgi'; -my $link = [ "$edit_url?", 'regionnum' ]; +my $link = [ "$edit_url?regionnum=", 'regionnum' ];  my $html_init =    'Regions and prefixes for VoIP and call billing.<BR><BR>'. diff --git a/httemplate/edit/cdr_type.cgi b/httemplate/edit/cdr_type.cgi new file mode 100644 index 000000000..5d2c66216 --- /dev/null +++ b/httemplate/edit/cdr_type.cgi @@ -0,0 +1,31 @@ +<% include('/elements/header.html', { title => 'CDR Types' } ) %> +<% include('/elements/menubar.html', 'Rate plans' => "${p}browse/rate.cgi" ) %> +<BR><% include('/elements/error.html') %> +<BR> +CDR types define types of phone usage for billing, such as voice  +calls and SMS messages.  Each CDR type must have a set of rates  +configured in the rate tables. +<BR> +<FORM METHOD="POST" ACTION="<% "${p}edit/process/cdr_type.cgi" %>"> +<% include('/elements/auto-table.html', +  'header' => [ 'Type#', 'Name' ], +  'fields' => [ qw( cdrtypenum cdrtypename ) ], +  'data'   => \@data, +  ) %> +<INPUT TYPE="submit" VALUE="Apply changes"> </FORM> <BR> +<% include('/elements/footer.html') %> +<%init> + +die "access denied" +  unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +my @data = ( +  map { [ $_->cdrtypenum, $_->cdrtypename ] } +  qsearch({  +    'table' => 'cdr_type', +    'hashref' => {}, +    'order_by' => 'ORDER BY cdrtypenum ASC' +  }) +); + +</%init> diff --git a/httemplate/edit/process/cdr_type.cgi b/httemplate/edit/process/cdr_type.cgi new file mode 100644 index 000000000..b661de75d --- /dev/null +++ b/httemplate/edit/process/cdr_type.cgi @@ -0,0 +1,42 @@ +% if ( $error ) { +%   $cgi->param('error', $error); +<% $cgi->redirect(popurl(2). "cdr_type.cgi?". $cgi->query_string ) %> +% } else { +<% $cgi->redirect(popurl(2). "cdr_type.cgi" ) %> +% } +<%init> +my $error = ''; +die "access denied"  +    unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +my %vars = $cgi->Vars; +warn Dumper(\%vars)."\n"; + +my %old = map { $_->cdrtypenum => $_ } qsearch('cdr_type', {}); + +my @new; +foreach ( keys(%vars) ) { +  my ($i) = /^cdrtypenum(\d+)$/ or next; +  my $cdrtypenum = $vars{"cdrtypenum$i"} or next; +  my $cdrtypename = $vars{"cdrtypename$i"} or next; +  # don't delete unchanged records +  if ( $old{$i} and $old{$i}->cdrtypename eq $cdrtypename ) { +    delete $old{$i}; +    next; +  } +  push @new, FS::cdr_type->new({  +    'cdrtypenum'  => $cdrtypenum, +    'cdrtypename' => $cdrtypename, +  }); +} +foreach (values(%old)) { +  $error = $_->delete; +  last if $error; +} +if(!$error) { +  foreach (@new) { +    $error = $_->insert; +    last if $error; +  } +} +</%init> diff --git a/httemplate/edit/rate.cgi b/httemplate/edit/rate.cgi index 13717dc1a..1abfb0d32 100644 --- a/httemplate/edit/rate.cgi +++ b/httemplate/edit/rate.cgi @@ -26,8 +26,24 @@ Rate plan  % if($rate->ratenum) {  <BR><BR><FONT SIZE="+2">Rates in this plan</FONT> +% if ( my $select_cdr_type = include('/elements/select-cdr_type.html', +%  'curr_value'   => $cdrtypenum, +%  'onchange'     => 'form.submit();', +%  'name_col'     => 'cdrtypename', +%  'value_col'    => 'cdrtypenum', +%  'empty_label'  => '(default)', +% ) ) { +<FORM ACTION="<%$cgi->url%>" METHOD="GET"> +<INPUT TYPE="hidden" NAME="ratenum" VALUE="<% $rate->ratenum %>"> +<INPUT TYPE="hidden" NAME="countrycode" VALUE="<% $countrycode %>"> +<FONT SIZE="+1">Usage type: <% $select_cdr_type %></FONT> +</FORM> +% } +  <% include('/edit/elements/rate_detail.html', -            'ratenum' => $rate->ratenum +            'ratenum'     => $rate->ratenum, +            'countrycode' => $countrycode, +            'cdrtypenum'  => $cdrtypenum,  ) %>  % } @@ -39,13 +55,21 @@ die "access denied"    unless $FS::CurrentUser::CurrentUser->access_right('Configuration');  my $rate; -if ( $cgi->keywords ) { -  my($query) = $cgi->keywords; -  $query =~ /^(\d+)$/; +if ( $cgi->param('ratenum') ) { +  $cgi->param('ratenum') =~ /^(\d+)$/;    $rate = qsearchs( 'rate', { 'ratenum' => $1 } );  } else { #adding    $rate = new FS::rate {};  }  my $action = $rate->ratenum ? 'Edit' : 'Add'; +my $countrycode = ''; +if ( $cgi->param('countrycode') =~ /^(\d+)$/ ) { +  $countrycode = $1; +} + +my $cdrtypenum = ''; +if ( $cgi->param('cdrtypenum') =~ /^(\d+)$/ ) { +  $cdrtypenum = $1; +}  </%init> diff --git a/httemplate/edit/rate_detail.html b/httemplate/edit/rate_detail.html index ec04e4cbb..19378209e 100644 --- a/httemplate/edit/rate_detail.html +++ b/httemplate/edit/rate_detail.html @@ -18,6 +18,7 @@                     { field=>'orig_regionnum',      type=>'hidden', },                     { field=>'dest_regionnum',      type=>'hidden', },                     { field=>'ratetimenum',         type=>'hidden', }, +                   { field=>'cdrtypenum',          type=>'hidden', },                     { field=>'dest_regionname',     type=>'fixed',  },                     { field=>'dest_prefixes_short', type=>'fixed',  },                     { field=>'rate_time_name',      type=>'fixed',  }, @@ -49,6 +50,9 @@          { ratenum        => $cgi->param('ratenum'),            dest_regionnum => $cgi->param('dest_regionnum'),            ratetimenum    => $cgi->param('ratetimenum'), +          cdrtypenum     => $cgi->param('cdrtypenum'), +          min_included   => 0, +          conn_charge    => 0,          }        },     ) diff --git a/httemplate/edit/rate_region.cgi b/httemplate/edit/rate_region.cgi index cae30030a..367bbafb6 100644 --- a/httemplate/edit/rate_region.cgi +++ b/httemplate/edit/rate_region.cgi @@ -35,17 +35,28 @@  </TABLE> -<BR><BR> +<BR>  <INPUT TYPE="submit" VALUE="<% $rate_region->regionnum ? "Apply changes" : "Add region" %>">  </FORM>  %# rate plan info, if the region has been created yet  % if($rate_region->regionnum) { -<BR> -<BR> -<FONT SIZE="+2">Rates in this region</FONT> +<BR><BR><FONT SIZE="+2">Rates in this region</FONT> +% if ( my $select_cdr_type = include('/elements/select-cdr_type.html', +%  'curr_value'   => $cdrtypenum, +%  'onchange'     => 'form.submit();', +%  'name_col'     => 'cdrtypename', +%  'value_col'    => 'cdrtypenum', +%  'empty_label'  => '(default)', +% ) ) { +<FORM ACTION="<%$cgi->url%>" METHOD="GET"> +<INPUT TYPE="hidden" NAME="regionnum"   VALUE="<% $rate_region->regionnum %>"> +<FONT SIZE="+1">Usage type: <% $select_cdr_type %></FONT> +</FORM> +% }  <% include('/edit/elements/rate_detail.html', -            'regionnum' => $rate_region->regionnum, +            'regionnum'   => $rate_region->regionnum, +            'cdrtypenum'  => $cdrtypenum,  ) %>  % } @@ -68,9 +79,8 @@ if ( $cgi->param('error') ) {    $rate_region = new FS::rate_region ( {      map { $_, scalar($cgi->param($_)) } fields('rate_region')    } ); -} elsif ( $cgi->keywords ) { -  my($query) = $cgi->keywords; -  $query =~ /^(\d+)$/ or die "unparsable regionnum"; +} elsif ( $cgi->param('regionnum') ) { +  $cgi->param('regionnum') =~ /^(\d+)$/ or die "unparseable regionnum";    $rate_region = qsearchs( 'rate_region', { 'regionnum' => $1 } )      or die "unknown regionnum $1\n";  } else { #adding @@ -91,5 +101,8 @@ if ( @rate_prefix ) {        unless $rate_prefix->countrycode eq $countrycode;    }  } - +my $cdrtypenum = ''; +if ( $cgi->param('cdrtypenum') =~ /^(\d+)$/ ) { +  $cdrtypenum = $1; +}  </%init> diff --git a/httemplate/elements/auto-table.html b/httemplate/elements/auto-table.html index 9c7dfd09a..49222745a 100644 --- a/httemplate/elements/auto-table.html +++ b/httemplate/elements/auto-table.html @@ -51,7 +51,9 @@ Values will be passed through as "mytable_id1", etc.    <TR>  %   my $col = 0;  %   for ( $col = 0; $col < scalar @fields; $col++ ) { -%     my $id = $prefix . $fields[$col] . $row; +%     my $id = $prefix . $fields[$col]; +%     # don't suffix rownum in the final, blank row +%     $id .= $row if $row < (scalar @data) - 1;       <TD>  %     my @o = @{ $select[$col] };  %     if( @o ) { @@ -117,7 +119,10 @@ $val eq $data[$row][$col] ? ' SELECTED' : ''%>><% shift @o %></OPTION>      var row = <% $prefix %>table.insertRow(-1);      var cells = <% $prefix %>_blank.cells;      for (i=0; i<cells.length; i++) { -      row.appendChild(cells[i].cloneNode(true)); +      var node = row.appendChild(cells[i].cloneNode(true)); +      var input = node.children[0]; +      input.id = input.id + row.sectionRowIndex; +      input.name = input.name + row.sectionRowIndex;      }      <% $prefix %>rownum++;    } diff --git a/httemplate/elements/select-cdr_type.html b/httemplate/elements/select-cdr_type.html new file mode 100644 index 000000000..9d260898a --- /dev/null +++ b/httemplate/elements/select-cdr_type.html @@ -0,0 +1,11 @@ +% if ( FS::Record->scalar_sql('SELECT COUNT(*) FROM cdr_type') ) { +<% include( '/elements/select-table.html', +              'table'       => 'cdr_type', +              'name_col'    => 'cdrtypenum', +              'empty_label' => '(none)', +              @_ +          ) +%> +% } +<%init> +</%init> | 
