From 40b466a6f51f20313f902be0935c0b08653bf1dd Mon Sep 17 00:00:00 2001 From: ivan Date: Sun, 30 Jan 2011 06:33:41 +0000 Subject: [PATCH] improve tax edit UI: add more counties & remove individual counties, RT#11144 --- httemplate/browse/cust_main_county.cgi | 135 ++++++++++++++++----- httemplate/edit/cust_main_county-add.cgi | 50 ++++++++ httemplate/edit/process/cust_main_county-add.cgi | 48 ++++++++ .../edit/process/cust_main_county-collapse.cgi | 15 ++- .../edit/process/cust_main_county-remove.cgi | 48 ++++++++ 5 files changed, 263 insertions(+), 33 deletions(-) create mode 100755 httemplate/edit/cust_main_county-add.cgi create mode 100755 httemplate/edit/process/cust_main_county-add.cgi create mode 100755 httemplate/edit/process/cust_main_county-remove.cgi diff --git a/httemplate/browse/cust_main_county.cgi b/httemplate/browse/cust_main_county.cgi index 04d1ae5bb..99c1712be 100755 --- a/httemplate/browse/cust_main_county.cgi +++ b/httemplate/browse/cust_main_county.cgi @@ -52,12 +52,14 @@ my $cell_style_sub = sub { if ( $cs_oldrow ne $row ) { if ( $cs_oldrow ) { if ( $cs_oldrow->country ne $row->country ) { - $cell_style = 'border-top:1px solid #000000'; + $cell_style = 'border-top:2px solid #000000'; } elsif ( $cs_oldrow->state ne $row->state ) { - $cell_style = 'border-top:1px solid #cccccc'; #default? + #$cell_style = 'border-top:1px solid #cccccc'; #default? + $cell_style = 'border-top:1px solid #bbbbbb'; } elsif ( $cs_oldrow->state eq $row->state ) { #$cell_style = 'border-top:dashed 1px dark gray'; - $cell_style = 'border-top:1px dashed #cccccc'; + #$cell_style = 'border-top:1px dashed #cccccc'; + $cell_style = ''; } } $cs_oldrow = $row; @@ -105,13 +107,42 @@ sub expand_link { ''; } +sub add_link { + my %param = @_; + + #if ( $ex_oldrow eq $param{'row'} ) { + # return ''; + #} else { + # $ex_oldrow = $param{'row'}; + #} + + my %below = ( 'county' => 'city', + 'state' => 'county', + ); + my $what = $below{ $param{'col' } }; + + my $taxnum = $param{'row'}->taxnum; + my $url = "${p}edit/cust_main_county-add.cgi?taxnum=$taxnum;what=$what"; + + ''. + include( '/elements/popup_link.html', + 'label' => $param{'label'}, + 'action' => $url, + 'actionlabel' => $param{'desc'}, + 'height' => 420, + #default# 'width' => 540, + #default# 'color' => '#333399', + ). + ''; +} + sub collapse_link { my %param = @_; my $row = $param{'row'}; my $col = $param{'col'}; return '' - if $col eq 'county' and $row->city + if $col eq 'state' and $row->city || qsearch({ 'table' => 'cust_main_county', 'hashref' => { @@ -122,20 +153,39 @@ sub collapse_link { 'order_by' => 'LIMIT 1', }); - my %above = ( 'city' => 'county', - 'county' => 'state', + my %below = ( 'county' => 'city', + 'state' => 'county', ); #XXX can still show the link when you have some counties broken down into #cities and others not :/ my $taxnum = $param{'row'}->taxnum; - my $url = "${p}edit/process/cust_main_county-collapse.cgi?$taxnum"; - $url = "javascript:collapse_areyousure('$url', '$col', '$above{$col}')"; + my $url = "${p}edit/process/cust_main_county-collapse.cgi?taxnum=$taxnum;". + 'country='. uri_escape($cgi->param('country')). ';'. + 'state='. uri_escape($cgi->param('state')). ';'. + 'county='. uri_escape($cgi->param('county')); + $url = "javascript:collapse_areyousure('$url', '$below{$col}', '$col')"; qq($param{'label'}); } +sub remove_link { + my %param = @_; + + my $row = $param{'row'}; + my $col = $param{'col'}; + + my $taxnum = $param{'row'}->taxnum; + my $url = "${p}edit/process/cust_main_county-remove.cgi?taxnum=$taxnum;". + 'country='. uri_escape($cgi->param('country')). ';'. + 'state='. uri_escape($cgi->param('state')). ';'. + 'county='. uri_escape($cgi->param('county')); + $url = "javascript:remove_areyousure('$url', '$col')"; + + qq($param{'label'}); + +} sub separate_taxclasses_link { my( $row ) = @_; @@ -165,11 +215,11 @@ my $html_init = < - - Click on add states to specify a country's tax rates by state or province. -
Click on add counties to specify a state's tax rates by county, or remove counties to remove per-county tax rates. -
Click on add cities to specify a county's tax rates by city, or remove cities to remove per-city tax rates. END $html_init .= "
Click on separate taxclasses to specify taxes per taxclass." @@ -397,41 +447,68 @@ my @links = ( '', '', '', '', ); my @link_onclicks = ( '', '', '', '', ); my $align = 'llll'; +my %seen_country = (); +my %seen_state = (); + my @fields = ( sub { my $country = shift->country; - code2country($country). " ($country)"; + return '' if $seen_country{$country}++; + code2country($country). " ($country)"; }, - sub { state_label($_[0]->state, $_[0]->country). - ( $_[0]->state - ? '' - : ' '. expand_link( desc => 'Add States', - row => $_[0], - label => 'add states', - ) - ) + sub { my $label = $seen_state{$_[0]->country}->{$_[0]->state}++ + ? '' : state_label($_[0]->state, $_[0]->country); + my $countylinks = ( $_[0]->county && $label ) + ? ' '. add_link( + desc => 'Add more counties', + col => 'state', + label=> 'add more counties', + row => $_[0], + cgi => $cgi, + ). + ' '. collapse_link( + col => 'state', + label=> 'remove all counties', + row => $_[0], + cgi => $cgi, + ) + : ''; + my $addlink = + ( $_[0]->state + ? '' + : ' '. expand_link( desc => 'Add States', + row => $_[0], + label => 'add states', + cgi => $cgi, + ) + ); + $label.$countylinks.$addlink; }, sub { $_[0]->county - ? $_[0]->county. ' '. - collapse_link( col => 'county', - label=> 'remove counties', + ? $_[0]->county. ' '. + remove_link( col => 'county', + label=> 'remove county', row => $_[0], + cgi => $cgi, ) - : '(all) '. + : '(all) '. expand_link( desc => 'Add Counties', row => $_[0], label => 'add counties', + cgi => $cgi, ); }, sub { $_[0]->city - ? $_[0]->city. ' '. - collapse_link( col => 'city', + ? $_[0]->city. ' '. + collapse_link( col => 'county', label=> 'remove cities', row => $_[0], + cgi => $cgi, ) - : '(all) '. + : '(all) '. expand_link( desc => 'Add Cities', row => $_[0], label => 'add cities', + cgi => $cgi, ); }, ); @@ -446,7 +523,7 @@ my @color = ( if ( $conf->exists('enable_taxclasses') ) { push @header, qq!Tax class (add new)!; push @header2, '(per-package classification)'; - push @fields, sub { $_[0]->taxclass || '(all) '. + push @fields, sub { $_[0]->taxclass || '(all) '. separate_taxclasses_link($_[0], 'Separate Taxclasses'). 'separate taxclasses' }; diff --git a/httemplate/edit/cust_main_county-add.cgi b/httemplate/edit/cust_main_county-add.cgi new file mode 100755 index 000000000..7821bd8d2 --- /dev/null +++ b/httemplate/edit/cust_main_county-add.cgi @@ -0,0 +1,50 @@ +<% include('/elements/header-popup.html', "Enter additional $title") %> + +<% include('/elements/error.html') %> + +
+ + + + + + +
+ + +
+ + + +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +$cgi->param('taxnum') =~ /^(\d+)$/ or die "Illegal taxnum"; +my $taxnum = $1; + +my $expansion = ''; +if ( $cgi->param('error') ) { + $expansion = $cgi->param('expansion'); +} + +my $cust_main_county = qsearchs('cust_main_county',{'taxnum'=>$taxnum}) + or die "cust_main_county.taxnum $taxnum not found"; + +$cgi->param('what') =~ /^(\w+)$/ or die "Illegal what"; +my $what = $1; + +my $title; +if ( $what eq 'city' ) { + $title = 'Cities'; +} elsif ( $what eq 'county' ) { + $title = 'Counties'; +} else { #??? + die "unknown what $what"; + #$title = 'States/Provinces'; +} + +my $p1 = popurl(1); + + diff --git a/httemplate/edit/process/cust_main_county-add.cgi b/httemplate/edit/process/cust_main_county-add.cgi new file mode 100755 index 000000000..352c6127c --- /dev/null +++ b/httemplate/edit/process/cust_main_county-add.cgi @@ -0,0 +1,48 @@ +<% include('/elements/header-popup.html', 'Addition successful' ) %> + + + + + +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +$cgi->param('taxnum') =~ /^(\d+)$/ or die "Illegal taxnum!"; +my $taxnum = $1; +my $cust_main_county = qsearchs('cust_main_county',{'taxnum'=>$taxnum}) + or die ("Unknown taxnum!"); + +my @expansion = split /[\n\r]{1,2}/, $cgi->param('expansion'); + +@expansion=map { + unless ( /^\s*([\w \!\@\#\$\%\&\(\)\-\+\;\:\'\"\,\.\?\/\=\[\]]+)\s*$/ ) { + $cgi->param('error', "Illegal item in expansion: $_"); + print $cgi->redirect(popurl(2). "cust_main_county-expand.cgi?". $cgi->query_string ); + myexit(); + } + $1; +} @expansion; + +foreach ( @expansion ) { + my(%hash)=$cust_main_county->hash; + my($new)=new FS::cust_main_county \%hash; + $new->setfield('taxnum',''); + if ( $cgi->param('what') eq 'state' ) { #?? + $new->setfield('state',$_); + } elsif ( $cgi->param('what') eq 'county' ) { + $new->setfield('county',$_); + } elsif ( $cgi->param('what') eq 'city' ) { + #uppercase cities in the US to try and agree with USPS validation + $new->setfield('city', $new->country eq 'US' ? uc($_) : $_ ); + } else { #??? + die 'unknown what '. $cgi->param('what'); + } + my $error = $new->insert; + die $error if $error; +} + + diff --git a/httemplate/edit/process/cust_main_county-collapse.cgi b/httemplate/edit/process/cust_main_county-collapse.cgi index 9608fc919..710e692fe 100755 --- a/httemplate/edit/process/cust_main_county-collapse.cgi +++ b/httemplate/edit/process/cust_main_county-collapse.cgi @@ -1,11 +1,15 @@ -<% $cgi->redirect(popurl(3). "browse/cust_main_county.cgi") %> +<% $cgi->redirect(popurl(3). "browse/cust_main_county.cgi?". + "country=". uri_escape($cgi->param('country')).";". + 'state='. uri_escape($cgi->param('state')). ';'. + 'county='. uri_escape($cgi->param('county')) + ) +%> <%init> die "access denied" unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); -my($query) = $cgi->keywords; -$query =~ /^(\d+)$/ or die "Illegal taxnum!"; +$cgi->param('taxnum') =~ /^(\d+)$/ or die "Illegal taxnum!"; my $taxnum = $1; my $cust_main_county = qsearchs('cust_main_county', { 'taxnum' => $taxnum } ) or die "Unknown taxnum $taxnum"; @@ -37,9 +41,12 @@ foreach my $delete ( qsearch('cust_main_county', \%search) ) { $cust_main_county->taxnum(''); if ( $cust_main_county->city ) { $cust_main_county->city(''); -} else { +} elsif ( $cust_main_county->county ) { $cust_main_county->county(''); +} else { + die "can't collapse that"; } + my $error = $cust_main_county->insert; die $error if $error; diff --git a/httemplate/edit/process/cust_main_county-remove.cgi b/httemplate/edit/process/cust_main_county-remove.cgi new file mode 100755 index 000000000..f018e6d65 --- /dev/null +++ b/httemplate/edit/process/cust_main_county-remove.cgi @@ -0,0 +1,48 @@ +<% $cgi->redirect(popurl(3). "browse/cust_main_county.cgi?". + "country=". uri_escape($cgi->param('country')).";". + 'state='. uri_escape($cgi->param('state')). ';'. + 'county='. uri_escape($cgi->param('county')) + ) +%> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +$cgi->param('taxnum') =~ /^(\d+)$/ or die "Illegal taxnum!"; +my $taxnum = $1; +my $cust_main_county = qsearchs('cust_main_county', { 'taxnum' => $taxnum } ) + or die "Unknown taxnum $taxnum"; + +#really should do this in a .pm & start transaction + +my %search = ( + 'country' => $cust_main_county->country, + 'state' => $cust_main_county->state, + ); + +$search{'county'} = $cust_main_county->county + if $cust_main_county->city; + +my $error = $cust_main_county->delete; +die $error if $error; + +unless ( qsearch('cust_main_county', \%search) ) { + + #if we're the last, clear our (state?)/county/city and reinsert + + $cust_main_county->taxnum(''); + if ( $cust_main_county->city ) { + $cust_main_county->city(''); + } elsif ( $cust_main_county->county ) { + $cust_main_county->county(''); + } else { + die "can't remove that"; + } + + my $error = $cust_main_county->insert; + die $error if $error; + +} + + -- 2.11.0