diff options
author | ivan <ivan> | 2009-01-05 00:26:54 +0000 |
---|---|---|
committer | ivan <ivan> | 2009-01-05 00:26:54 +0000 |
commit | 125fb1a284ae96b46fe433c418aafa87862c4382 (patch) | |
tree | cb9485c9cfd7e685bc63ea40fe214f80c18407b1 | |
parent | c23d6e1673dbec98fe9d778ee55962d2cbd145d5 (diff) |
add rate copying, RT#4431
-rw-r--r-- | FS/FS/rate_prefix.pm | 23 | ||||
-rw-r--r-- | httemplate/browse/rate.cgi | 7 | ||||
-rw-r--r-- | httemplate/elements/checkboxes-table-name.html | 88 | ||||
-rw-r--r-- | httemplate/elements/checkboxes.html | 103 | ||||
-rw-r--r-- | httemplate/elements/select-rate.html | 9 | ||||
-rw-r--r-- | httemplate/elements/tr-select-rate.html | 21 | ||||
-rw-r--r-- | httemplate/misc/copy-rate_detail.html | 61 | ||||
-rw-r--r-- | httemplate/misc/process/copy-rate_detail.html | 61 |
8 files changed, 294 insertions, 79 deletions
diff --git a/FS/FS/rate_prefix.pm b/FS/FS/rate_prefix.pm index 42b004f5b..ce780fefe 100644 --- a/FS/FS/rate_prefix.pm +++ b/FS/FS/rate_prefix.pm @@ -2,7 +2,7 @@ package FS::rate_prefix; use strict; use vars qw( @ISA ); -use FS::Record qw( qsearch qsearchs ); +use FS::Record qw( qsearch qsearchs dbh ); use FS::rate_region; @ISA = qw(FS::Record); @@ -127,6 +127,27 @@ sub rate_region { =back +=head1 CLASS METHODS + +=over 4 + +=item all_countrycodes + +Returns a list of all countrycodes listed in rate_prefix + +=cut + +sub all_countrycodes { + #my $class = shift; + my $sql = + "SELECT DISTINCT(countrycode) FROM rate_prefix ORDER BY countrycode"; + my $sth = dbh->prepare($sql) or die dbh->errstr; + $sth->execute or die $sth->errstr; + map $_->[0], @{ $sth->fetchall_arrayref }; +} + +=back + =head1 BUGS =head1 SEE ALSO diff --git a/httemplate/browse/rate.cgi b/httemplate/browse/rate.cgi index b20c45c0c..911b2fd28 100644 --- a/httemplate/browse/rate.cgi +++ b/httemplate/browse/rate.cgi @@ -17,12 +17,8 @@ %> <%once> -my $sth = dbh->prepare("SELECT DISTINCT(countrycode) FROM rate_prefix") - or die dbh->errstr; -$sth->execute or die $sth->errstr; -my @all_countrycodes = map $_->[0], @{ $sth->fetchall_arrayref }; my $all_countrycodes = join("\n", map qq(<OPTION VALUE="$_">$_), - @all_countrycodes + FS::rate_prefix->all_countrycodes ); my $rates_sub = sub { @@ -51,6 +47,7 @@ die "access denied" my $html_init = 'Rate plans for VoIP and call billing.<BR><BR>'. qq!<A HREF="${p}edit/rate.cgi"><I>Add a rate plan</I></A>!. + qq! | <A HREF="${p}misc/copy-rate_detail.html"><I>Copy rates between plans</I></A>!. '<BR><BR> <SCRIPT> function rate_areyousure(href) { diff --git a/httemplate/elements/checkboxes-table-name.html b/httemplate/elements/checkboxes-table-name.html index b236787b6..31652f330 100644 --- a/httemplate/elements/checkboxes-table-name.html +++ b/httemplate/elements/checkboxes-table-name.html @@ -41,79 +41,12 @@ Example: </%doc> -<TABLE CELLSPACING=0 CELLPADDING=0> - -<TR> - <TD COLSPAN=2 ALIGN="center"><FONT SIZE="-1">( - <A HREF="javascript:setAll<%$prefix%>(true)">select all</A> | - <A HREF="javascript:setAll<%$prefix%>(false)">unselect all</A> | - <A HREF="javascript:toggleAll<%$prefix%>()">toggle all</A> - )</FONT></TD> -</TR> - -% my $num=0; -% foreach my $item ( @{ $opt{'names_list'} } ) { -% -% my $name = ref($item) ? $item->[0] : $item; -% ( my $display = $name ) =~ s/ / /g; -% $display .= $item->[1]{note} if ref($item) && $item->[1]{note}; -% my $desc = ref($item) && $item->[1]{desc} ? $item->[1]{desc} : ''; -% -% my $checked; -% if ( $cgi->param('error') ) { -% -% $checked = $cgi->param($opt{'link_table'}. ".$name" ) -% ? 'CHECKED' -% : ''; -% -% } else { -% -% $checked = -% qsearchs( $opt{'link_table'}, { -% $source_pkey => $sourcenum, -% $opt{'name_col'} => $name, -% %$link_static, -% } ) -% ? 'CHECKED' -% : '' -% -% } - - <TR> - <TD VALIGN="top"> - <INPUT TYPE="checkbox" NAME="<% $opt{'link_table'}. ".$name" %>" <% $checked %> ID="<%$prefix.$num++%>" VALUE="ON"> - </TD> - <TD><% $display %> -% if ( $desc ) { - <BR><FONT SIZE="-2"><% $desc %></FONT> -% } - </TD> - </TR> - -% } - -</TABLE> - -<SCRIPT TYPE="text/javascript"> - - function setAll<%$prefix%>(setTo) { -% for ( 0 .. ($num-1) ) { - document.getElementById('<%$prefix.$_%>').checked = setTo; -% } - } - - function toggleAll<%$prefix%>(setTo) { -% for ( 0 .. ($num-1) ) { - var element = document.getElementById('<%$prefix.$_%>'); - if ( element.checked == true ) { - element.checked = false; - } else { - element.checked = true; - } -% } - } - -</SCRIPT> +<% include('checkboxes.html', + 'names_list' => $opt{'names_list'}, + 'checked_callback' => $checked_callback, + 'element_name_prefix' => $opt{'link_table'}. '.', + ) +%> <%init> @@ -145,4 +78,13 @@ $source_pkey = $opt{'num_col'} || $source_pkey; my $link_static = $opt{'link_static'} || {}; +my $checked_callback = sub { + my( $cgi, $name ) = @_; + qsearchs( $opt{'link_table'}, { + $source_pkey => $sourcenum, + $opt{'name_col'} => $name, + %$link_static, + }); +}; + </%init> diff --git a/httemplate/elements/checkboxes.html b/httemplate/elements/checkboxes.html new file mode 100644 index 000000000..126224538 --- /dev/null +++ b/httemplate/elements/checkboxes.html @@ -0,0 +1,103 @@ +<%doc> + +Example: + + include( '/elements/checkboxes.html', + + # required + + #? 'name_callback' => sub { }, + + 'names_list' => [ 'value', + 'other value', + [ 'complex value' => { 'desc' => "Add'l description", + 'note' => ' *', + } + ], + ], + + 'element_name_prefix' => "$link_table.", + + #recommended + + 'checked_callback' => sub { my( $cgi, $name ) = @_; }, + + ) + +</%doc> + +<TABLE CELLSPACING=0 CELLPADDING=0> + +<TR> + <TD COLSPAN=2 ALIGN="center"><FONT SIZE="-1">( + <A HREF="javascript:setAll<%$prefix%>(true)">select all</A> | + <A HREF="javascript:setAll<%$prefix%>(false)">unselect all</A> | + <A HREF="javascript:toggleAll<%$prefix%>()">toggle all</A> + )</FONT></TD> +</TR> + +% my $num=0; +% foreach my $item ( @{ $opt{'names_list'} } ) { +% +% my $name = ref($item) ? $item->[0] : $item; +% ( my $display = $name ) =~ s/ / /g; +% $display .= $item->[1]{note} if ref($item) && $item->[1]{note}; +% my $desc = ref($item) && $item->[1]{desc} ? $item->[1]{desc} : ''; +% +% my $callback = +% ( $cgi->param('error') ? 'error_' : '' ). 'checked_callback'; +% my $checked = &{ $opt{$callback} }( $cgi, $name ) ? 'CHECKED' : ''; + + <TR> + <TD VALIGN="top"> + <INPUT TYPE="checkbox" NAME="<% $opt{'element_name_prefix'}. $name %>" <% $checked %> ID="<%$prefix.$num++%>" VALUE="ON"> + </TD> + <TD><% $display %> +% if ( $desc ) { + <BR><FONT SIZE="-2"><% $desc %></FONT> +% } + </TD> + </TR> + +% } + +</TABLE> + +<SCRIPT TYPE="text/javascript"> + + function setAll<%$prefix%>(setTo) { +% for ( 0 .. ($num-1) ) { + document.getElementById('<%$prefix.$_%>').checked = setTo; +% } + } + + function toggleAll<%$prefix%>(setTo) { +% for ( 0 .. ($num-1) ) { + var element = document.getElementById('<%$prefix.$_%>'); + if ( element.checked == true ) { + element.checked = false; + } else { + element.checked = true; + } +% } + } + +</SCRIPT> + +<%init> + +my( %opt ) = @_; + +my @pset = ( 'a'..'z', 'A'..'Z', '0'..'9' ); + +my $prefix = $opt{prefix} + || join('', map $pset[ int(rand $#pset) ], (0..20) ); + +$opt{checked_callback} ||= sub {}; + +$opt{'error_checked_callback'} ||= sub { + my( $cgi, $name ) = @_; + $cgi->param($opt{'element_name_prefix'}. $name ); +}; + +</%init> diff --git a/httemplate/elements/select-rate.html b/httemplate/elements/select-rate.html new file mode 100644 index 000000000..83a7add06 --- /dev/null +++ b/httemplate/elements/select-rate.html @@ -0,0 +1,9 @@ +<% include( '/elements/select-table.html', + 'table' => 'rate', + 'name_col' => 'ratename', + 'empty_label' => 'Select rate plan', + #'hashref' => { 'disabled' => '' }, + 'order_by' => ' ORDER BY ratenum', #ratename ? + @_, + ) +%> diff --git a/httemplate/elements/tr-select-rate.html b/httemplate/elements/tr-select-rate.html new file mode 100644 index 000000000..27f2645af --- /dev/null +++ b/httemplate/elements/tr-select-rate.html @@ -0,0 +1,21 @@ +% unless ( $opt{'js_only'} ) { + + <% include('tr-td-label.html', @_ ) %> + + <TD <% $style %>> +% } + + <% include( '/elements/select-rate.html', %opt ) %> + +% unless ( $opt{'js_only'} ) { + </TD> + </TR> +% } +<%init> + +my( %opt ) = @_; + +my $style = $opt{'cell_style'} ? 'STYLE="'. $opt{'cell_style'}. '"' : ''; + +</%init> + diff --git a/httemplate/misc/copy-rate_detail.html b/httemplate/misc/copy-rate_detail.html new file mode 100644 index 000000000..3d328ce59 --- /dev/null +++ b/httemplate/misc/copy-rate_detail.html @@ -0,0 +1,61 @@ +<% include( '/elements/header.html', 'Copy rates between plans', menubar( + 'View all rate plans' => "${p}browse/rate.cgi", + )) +%> + +<% include('/elements/error.html') %> + +<FORM ACTION="process/copy-rate_detail.html"> + +<% ntable('#cccccc') %> + + <% include( '/elements/tr-justtitle.html', 'value' => 'Copy rates' ) %> + + <% include( '/elements/tr-select-rate.html', + 'label' => 'From rate plan', + 'element_name' => 'src_ratenum', + ) + %> + + <% include( '/elements/tr-select-rate.html', + 'label' => 'To rate plan', + 'element_name' => 'dst_ratenum', + ) + %> + + <TR> + <TD COLSPAN=2>Copy country codes</TD> + </TR> + + <TR> + <TD COLSPAN=2> + + <% include( '/elements/checkboxes.html', + 'names_list' => [ FS::rate_prefix->all_countrycodes ], + 'element_name_prefix' => 'countrycode', + ) + %> + </TD> + </TR> + + <TR> + <TD COLSPAN=2 ALIGN="center"> + <INPUT TYPE="submit" VALUE="Copy rates"> + </TD> + </TR> + +</TABLE> + +</FORM> + +<% include('/elements/footer.html') %> + +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +#should have some javascript that enables submit button only when both src & dst +#rates are chosen + +</%init> diff --git a/httemplate/misc/process/copy-rate_detail.html b/httemplate/misc/process/copy-rate_detail.html new file mode 100644 index 000000000..87a674566 --- /dev/null +++ b/httemplate/misc/process/copy-rate_detail.html @@ -0,0 +1,61 @@ +%# if ( $error ) { +%# <% $cgi->redirect(popurl(2).'copy-rate_detail.html?'. $cgi->query_string ) %> +%# } else { +<% include('/elements/header.html', 'Rates copied', + menubar( 'View all rate plans' => popurl(3).'browse/rate.cgi' ), + ) %> +%# } +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +$cgi->param('src_ratenum') =~ /^(\d+)$/ or die 'Illegal src_ratenum'; +my $src_ratenum = $1; + +$cgi->param('dst_ratenum') =~ /^(\d+)$/ or die 'Illegal src_ratenum'; +my $dst_ratenum = $1; + +my @countrycodes = map { /^countrycode(\d+)$/ or die; $1 } + grep { /^countrycode(\d+)$/ && $cgi->param($_) } + $cgi->param; + +foreach my $countrycode ( @countrycodes ) { + + my @src_rate_detail = qsearch({ + 'table' => 'rate_detail', + 'addl_from' => 'JOIN rate_region'. + ' ON ( rate_detail.dest_regionnum = rate_region.regionnum )', + 'hashref' => { 'ratenum' => $src_ratenum }, + 'extra_sql' => + "AND 0 < ( SELECT COUNT(*) FROM rate_prefix + WHERE rate_prefix.regionnum = rate_region.regionnum + AND countrycode = '$countrycode' + ) + ", + }); + + foreach my $src_rate_detail ( @src_rate_detail ) { + + my %hash = ( + 'ratenum' => $dst_ratenum, + map { $_ => $src_rate_detail->get($_) } + qw( orig_regionnum dest_regionnum ) + ); + + my $dst_rate_detail = qsearchs( 'rate_detail', \%hash) + || new FS::rate_detail \%hash; + + $dst_rate_detail->$_( $src_rate_detail->get($_) ) + foreach qw( min_included min_charge sec_granularity classnum ); + + my $method = $dst_rate_detail->ratedetailnum ? 'replace' : 'insert'; + + my $error = $dst_rate_detail->$method(); + + die $error if $error; # "shouldn't" happen + + } +} + +</%init> |