From 1f0e0fb65fdd32d57a3134c018d5a1dc0f09e249 Mon Sep 17 00:00:00 2001 From: ivan Date: Fri, 4 Jan 2008 02:42:07 +0000 Subject: [PATCH] new tax rate editor --- httemplate/browse/cust_main_county.cgi | 383 ++++++++++++--------- httemplate/edit/cust_main_county-expand.cgi | 122 +++---- httemplate/edit/cust_main_county.html | 62 ++++ .../edit/process/cust_main_county-expand.cgi | 112 +++--- httemplate/edit/process/cust_main_county.html | 6 + httemplate/edit/process/elements/process.html | 82 +++-- httemplate/search/elements/search.html | 112 ++++-- 7 files changed, 548 insertions(+), 331 deletions(-) create mode 100644 httemplate/edit/cust_main_county.html create mode 100644 httemplate/edit/process/cust_main_county.html diff --git a/httemplate/browse/cust_main_county.cgi b/httemplate/browse/cust_main_county.cgi index 3bbbb4b47..3e67b1122 100755 --- a/httemplate/browse/cust_main_county.cgi +++ b/httemplate/browse/cust_main_county.cgi @@ -1,170 +1,225 @@ -<% include('/elements/header.html', "Tax Rate Listing", menubar( - 'Edit tax rates' => $p. "edit/cust_main_county.cgi", -)) %> - - Click on expand country to specify a country's tax rates by state. -
Click on expand state to specify a state's tax rates by county. -% -%my $conf = new FS::Conf; -%my $enable_taxclasses = $conf->exists('enable_taxclasses'); -% -%if ( $enable_taxclasses ) { - - -
Click on expand taxclasses to specify tax classes -% } - - -

-<% table() %> - - - Country - State - County - Taxclass
(per-package classification) - Tax name
(printed on invoices) - Tax - Exemption - -% -%my @regions = sort { $a->country cmp $b->country -% or $a->state cmp $b->state -% or $a->county cmp $b->county -% or $a->taxclass cmp $b->taxclass -% } qsearch('cust_main_county',{}); -% -%my $sup=0; -%#foreach $cust_main_county ( @regions ) { -%for ( my $i=0; $i<@regions; $i++ ) { -% my $cust_main_county = $regions[$i]; -% my $hashref = $cust_main_county->hashref; -% -% - - - <% $hashref->{country} %> -% -% -% my $j; -% if ( $sup ) { -% $sup--; -% } else { +<% include( 'elements/browse.html', + 'title' => 'Tax Rates', + 'name_singular' => 'tax rate', + 'html_init' => $html_init, + 'html_posttotal' => $html_posttotal, + 'query' => { + 'table' => 'cust_main_county', + 'hashref' => $hashref, + 'order_by' => + 'ORDER BY country, state, county, taxclass', + }, + 'count_query' => $count_query, + 'header' => \@header, + 'header2' => \@header2, + 'fields' => \@fields, + 'align' => $align, + 'color' => \@color, + 'cell_style' => \@cell_style, + 'links' => \@links, + 'link_onclicks' => \@link_onclicks, + ) +%> % -% #lookahead -% for ( $j=1; $i+$j<@regions; $j++ ) { -% last if $hashref->{country} ne $regions[$i+$j]->country -% || $hashref->{state} ne $regions[$i+$j]->state -% || $hashref->{tax} != $regions[$i+$j]->tax -% || $hashref->{exempt_amount} != $regions[$i+$j]->exempt_amount -% || $hashref->{setuptax} ne $regions[$i+$j]->setuptax -% || $hashref->{recurtax} ne $regions[$i+$j]->recurtax; -% } +% # collapse state +% # % } % -% my $newsup=0; -% if ( $j>1 && $i+$j+1 < @regions -% && ( $hashref->{state} ne $regions[$i+$j+1]->state -% || $hashref->{country} ne $regions[$i+$j+1]->country -% ) -% && ( ! $i -% || $hashref->{state} ne $regions[$i-1]->state -% || $hashref->{country} ne $regions[$i-1]->country -% ) -% ) { -% $sup = $j-1; -% } else { -% $j = 1; -% } -% -% - - - <% - $hashref->{state} - ? ' BGCOLOR="#ffffff">'. $hashref->{state} - : qq! BGCOLOR="#cccccc">(ALL) !. - qq!expand country! - %> -% if ( $j>1 ) { - - collapse state -% } - - - -% } -% # $sup=$newsup; - - - {county} ) { -% - BGCOLOR="#ffffff"><% $hashref->{county} %> -% } else { -% - BGCOLOR="#cccccc">(ALL) -% if ( $hashref->{state} ) { - - expand state -% } -% } - - - - {taxclass} ) { -% - BGCOLOR="#ffffff"><% $hashref->{taxclass} %> -% } else { -% - BGCOLOR="#cccccc">(ALL) -% if ( $enable_taxclasses ) { - - expand taxclasses -% } -% } - - - - {taxname} ) { -% - BGCOLOR="#ffffff"><% $hashref->{taxname} %> -% } else { -% - BGCOLOR="#cccccc">Tax -% } - - - - <% $hashref->{tax} %>% - - -% if ( $hashref->{exempt_amount} > 0 ) { - - $<% sprintf("%.2f", $hashref->{exempt_amount} ) %> per month
-% } -% if ( $hashref->{setuptax} =~ /^Y$/i ) { - - Setup fee
-% } -% if ( $hashref->{recurtax} =~ /^Y$/i ) { - - Recurring fee
-% } - - - - - -% } - - - - -<% include('/elements/footer.html') %> +<%once> + +my $conf = new FS::Conf; +my $money_char = $conf->config('money_char') || '$'; + +my @manual_countries = ( 'US', 'CA', 'AU', 'NZ', 'GB' ); #some manual ordering +my @all_countries = ( @manual_countries, + grep { my $c = $_; ! grep { $c eq $_ } @manual_countries } + map { $_->country } + qsearch({ + 'select' => 'country', + 'table' => 'cust_main_county', + 'hashref' => {}, + 'extra_sql' => 'GROUP BY country', + }) + ); + +my $exempt_sub = sub { + my $cust_main_county = shift; + + my @exempt = (); + push @exempt, + sprintf("$money_char%.2f per month", $cust_main_county->exempt_amount ) + if $cust_main_county->exempt_amount > 0; + + push @exempt, 'Setup fee' + if $cust_main_county->setuptax =~ /^Y$/i; + + push @exempt, 'Recurring fee' + if $cust_main_county->recurtax =~ /^Y$/i; + + [ map [ {'data'=>$_} ], @exempt ]; +}; + +my $oldrow; +my $cell_style; +my $cell_style_sub = sub { + my $row = shift; + if ( $oldrow ne $row ) { + if ( $oldrow ) { + if ( $oldrow->country ne $row->country ) { + $cell_style = 'border-top:1px solid #000000'; + } elsif ( $oldrow->state ne $row->state ) { + $cell_style = 'border-top:1px solid #cccccc'; #default? + } elsif ( $oldrow->state eq $row->state ) { + #$cell_style = 'border-top:dashed 1px dark gray'; + $cell_style = 'border-top:1px dashed #cccccc'; + } + } + $oldrow = $row; + } + return $cell_style; +}; + +#my $edit_link = [ "${p}edit/cust_main_county.html", 'taxnum' ]; +my $edit_link = [ 'javascript:void(0);', sub { ''; } ]; + +my $edit_onclick = sub { + my $row = shift; + my $taxnum = $row->taxnum; + my $color = '#333399'; + qq!overlib( OLiframeContent('${p}edit/cust_main_county.html?$taxnum', 540, 420, 'edit_cust_main_county_popup' ), CAPTION, 'Edit tax rate', STICKY, AUTOSTATUSCAP, MIDX, 0, MIDY, 0, DRAGGABLE, CLOSECLICK, BGCOLOR, '$color', CGCOLOR, '$color' ); return false;!; +}; + +sub expand_link { + my( $row, $desc, %opt ) = @_; + my $taxnum = $row->taxnum; + $taxnum = "taxclass$taxnum" if $opt{'taxclass'}; + my $color = '#333399'; + qq!!; +} + + <%init> + die "access denied" unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +#my $conf = new FS::Conf; +#my $money_char = $conf->config('money_char') || '$'; +my $enable_taxclasses = $conf->exists('enable_taxclasses'); + +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."; +$html_init .= "
Click on add taxclasses to specify tax classes." + if $enable_taxclasses; +$html_init .= '

'; + +$html_init .= qq( + + + + +); + +my $filter_country = ''; +if ( $cgi->param('filter_country') =~ /^(\w\w)$/ ) { + $filter_country = $1; +} +$cgi->delete('filter_country'); +$cgi->param('dummy', 1); + +my $country_filter_change = + "window.location = '". + $cgi->self_url. ";filter_country=' + this.options[this.selectedIndex].value;"; + +my $html_posttotal = + '(show country: '. + qq()'; + +my $hashref = {}; +my $count_query = 'SELECT COUNT(*) FROM cust_main_county'; +if ( $filter_country ) { + $hashref->{'country'} = $filter_country; + $count_query .= " WHERE country = '$filter_country'"; +} + +$cell_style = ''; + +my @header = ( 'Country', 'State/Province', 'County',); +my @header2 = ( '', '', '', ); +my @links = ( '', '', '', ); +my @link_onclicks = ( '', '', '', ); +my $align = 'lll'; + +my @fields = ( + sub { my $country = shift->country; + code2country($country). " ($country)"; + }, + sub { state_label($_[0]->state, $_[0]->country). + ( $_[0]->state + ? '' + : ' '. expand_link($_[0], 'Add States'). + 'add states
' + ) + }, + sub { $_[0]->county || '(all) '. + expand_link($_[0], 'Add Counties'). + 'add counties
' + }, +); + +my @color = ( + '000000', + sub { shift->state ? '000000' : '999999' }, + sub { shift->county ? '000000' : '999999' }, +); + +if ( $conf->exists('enable_taxclasses') ) { + push @header, 'Tax class'; + push @header2, '(per-package classification)'; + push @fields, sub { $_[0]->taxclass || '(all) '. + expand_link($_[0], 'Add Taxclasses', 'taxclass'=>1). + 'add taxclasses' + }; + push @color, sub { shift->taxclass ? '000000' : '999999' }; + push @links, ''; + push @link_onclicks, ''; + $align .= 'l'; +} + +push @header, 'Tax name', + 'Rate', #'Tax', + 'Exemptions', + ; + +push @header2, '(printed on invoices)', + '', + '', + ; + +push @fields, + sub { shift->taxname || 'Tax' }, + sub { shift->tax. '% (edit)' }, + $exempt_sub, +; + +push @color, + sub { shift->taxname ? '000000' : '666666' }, + sub { shift->tax ? '000000' : '666666' }, + '000000', +; + +$align .= 'lrl'; + +my @cell_style = map $cell_style_sub, (1..scalar(@header)); + +push @links, '', $edit_link, ''; +push @link_onclicks, '', $edit_onclick, ''; + diff --git a/httemplate/edit/cust_main_county-expand.cgi b/httemplate/edit/cust_main_county-expand.cgi index f56d31941..abf8e27f2 100755 --- a/httemplate/edit/cust_main_county-expand.cgi +++ b/httemplate/edit/cust_main_county-expand.cgi @@ -1,59 +1,65 @@ - -% -% -%my($taxnum, $delim, $expansion, $taxclass ); -%my($query) = $cgi->keywords; -%if ( $cgi->param('error') ) { -% $taxnum = $cgi->param('taxnum'); -% $delim = $cgi->param('delim'); -% $expansion = $cgi->param('expansion'); -% $taxclass = $cgi->param('taxclass'); -%} else { -% $query =~ /^(taxclass)?(\d+)$/ -% or die "Illegal taxnum (query $query)"; -% $taxclass = $1 ? 'taxclass' : ''; -% $taxnum = $2; -% $delim = 'n'; -% $expansion = ''; -%} -% -%my $cust_main_county = qsearchs('cust_main_county',{'taxnum'=>$taxnum}) -% or die "cust_main_county.taxnum $taxnum not found"; -%if ( $taxclass ) { -% die "Can't expand entry!" if $cust_main_county->getfield('taxclass'); -%} else { -% die "Can't expand entry!" if $cust_main_county->getfield('county'); -%} -% -%my $p1 = popurl(1); -%print header("Tax Rate (expand)", menubar( -% 'Main Menu' => popurl(2), -%)); -% -%print qq!Error: !, $cgi->param('error'), -% "" -% if $cgi->param('error'); -% -%print < -% -% -% Separate by -%END -%print 'line (broken on some browsers) or', -% 'whitespace.'; -%print < -%
-% -% -% -% -%END -% -% +<% include('/elements/header-popup.html', "Enter $title") %> +<% include('/elements/error.html') %> + +
+ + + + + + +
+ + +
+ + + +<%init> + +my($taxnum, $expansion, $taxclass); +my($query) = $cgi->keywords; +if ( $cgi->param('error') ) { + $taxnum = $cgi->param('taxnum'); + $expansion = $cgi->param('expansion'); + $taxclass = $cgi->param('taxclass'); +} else { + $query =~ /^(taxclass)?(\d+)$/ + or die "Illegal taxnum (query $query)"; + $taxclass = $1 ? 'taxclass' : ''; + $taxnum = $2; + $expansion = ''; +} + +my $cust_main_county = qsearchs('cust_main_county',{'taxnum'=>$taxnum}) + or die "cust_main_county.taxnum $taxnum not found"; + +my $title; +if ( $taxclass ) { + die "Can't expand entry!" if $cust_main_county->taxclass; + + $title = 'Tax Classes'; + + # prepopuplate with other tax classes... which should really have a primary + # key of their own... also this could be more efficient in the error case... + my $sth = dbh->prepare("SELECT DISTINCT taxclass FROM cust_main_county") + or die dbh->errstr; + $sth->execute or die $sth->errstr; + my %taxclasses = map { $_->[0] => 1 } @{$sth->fetchall_arrayref}; + $expansion ||= join("\n", grep $_, keys %taxclasses ); + +} else { + die "Can't expand entry!" if $cust_main_county->county; + + if ( $cust_main_county->state ) { + $title = 'Counties'; + } else { + $title = 'States/Provinces'; + } + +} + +my $p1 = popurl(1); + + diff --git a/httemplate/edit/cust_main_county.html b/httemplate/edit/cust_main_county.html new file mode 100644 index 000000000..510839d71 --- /dev/null +++ b/httemplate/edit/cust_main_county.html @@ -0,0 +1,62 @@ +<% include('elements/edit.html', + 'popup' => 1, + 'name' => 'Tax rate', #Edit tax rate + 'table' => 'cust_main_county', + 'labels' => { 'taxnum' => 'Tax', + 'country' => 'Country', + 'state' => 'State', + 'county' => 'County', + 'taxclass' => 'Tax class', + 'taxname' => 'Tax name', + 'tax' => 'Tax rate', + 'setuptax' => 'This tax not applicable to setup fees', + 'recurtax' => 'This tax not applicable to recurring fees', + 'exempt_amount' => 'Monthly exemption per customer ($25 "Texas tax")', + }, + 'fields' => \@fields, + ) +%> +<%once> + +my $conf = new FS::Conf; + + + +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +my $taxnum; +if ( $cgi->param('error') ) { + $cgi->param('taxnum') =~ /^(\d+)$/ or die 'error, but no taxnum'; + $taxnum = $1; +} else { + my($query) = $cgi->keywords; + $query =~ /^(\d+)$/ or die 'no taxnum'; + $taxnum = $1; +} + +my $cust_main_county = qsearchs('cust_main_county', { 'taxnum' => $taxnum }) + or die "unknown taxnum $1"; + +my @fields = ( + { field=>'country', type=>'fixed-country', }, + { field=>'state', type=>'fixed-state', }, + { field=>'county', type=>'fixed', }, +); + +push @fields, { field=>'taxclass', type=>'fixed', } + if $conf->exists('enable_taxclasses'); + +push @fields, + 'taxname', + { field=>'tax', type=>'percentage', }, + + { type=>'tablebreak-tr-title', value=>'Exemptions' }, + { field=>'setuptax', type=>'checkbox', value=>'Y', }, + { field=>'recurtax', type=>'checkbox', value=>'Y', }, + { field=>'exempt_amount', type=>'money', }, +; + + diff --git a/httemplate/edit/process/cust_main_county-expand.cgi b/httemplate/edit/process/cust_main_county-expand.cgi index e550e8b4a..4e04f37fc 100755 --- a/httemplate/edit/process/cust_main_county-expand.cgi +++ b/httemplate/edit/process/cust_main_county-expand.cgi @@ -1,59 +1,55 @@ -% -% -%$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; -%if ( $cgi->param('delim') eq 'n' ) { -% @expansion=split(/\n/,$cgi->param('expansion')); -%} elsif ( $cgi->param('delim') eq 's' ) { -% @expansion=split(' ',$cgi->param('expansion')); -%} else { -% die "Illegal delim!"; -%} -% -%@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('taxclass') ) { -% $new->setfield('taxclass', $_); -% } elsif ( ! $cust_main_county->state ) { -% $new->setfield('state',$_); -% } else { -% $new->setfield('county',$_); -% } -% #if (datasrc =~ m/Pg/) -% #{ -% # $new->setfield('tax',0.0); -% #} -% my($error)=$new->insert; -% die $error if $error; -%} -% -%unless ( qsearch( 'cust_main', { -% 'state' => $cust_main_county->state, -% 'county' => $cust_main_county->county, -% 'country' => $cust_main_county->country, -% } ) -% || ! @expansion -%) { -% my($error)=($cust_main_county->delete); -% die $error if $error; -%} -% -%print $cgi->redirect(popurl(3). "browse/cust_main_county.cgi"); -% -% +<% include('/elements/header-popup.html', 'Addition successful' ) %> + + + + +<%init> + +$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'); +#warn scalar(@expansion); +#warn "$_: $expansion[$_]\n" foreach (0..$#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('taxclass') ) { + $new->setfield('taxclass', $_); + } elsif ( ! $cust_main_county->state ) { + $new->setfield('state',$_); + } else { + $new->setfield('county',$_); + } + my $error = $new->insert; + die $error if $error; +} + +unless ( qsearch( 'cust_main', { + 'state' => $cust_main_county->state, + 'county' => $cust_main_county->county, + 'country' => $cust_main_county->country, + } ) + || ! @expansion +) { + my $error = $cust_main_county->delete; + die $error if $error; +} + + diff --git a/httemplate/edit/process/cust_main_county.html b/httemplate/edit/process/cust_main_county.html new file mode 100644 index 000000000..3d9d20b85 --- /dev/null +++ b/httemplate/edit/process/cust_main_county.html @@ -0,0 +1,6 @@ +<% include( 'elements/process.html', + 'table' => 'cust_main_county', + 'popup_reload' => 'Tax changed', #a popup "parent reload" for now + #someday change the individual element and go away instead + ) +%> diff --git a/httemplate/edit/process/elements/process.html b/httemplate/edit/process/elements/process.html index 19d3fbef1..a671ca118 100644 --- a/httemplate/edit/process/elements/process.html +++ b/httemplate/edit/process/elements/process.html @@ -17,9 +17,11 @@ Example: # optional ### - 'viewall_dir' => '', #'search' or 'browse', defaults to 'search' + 'viewall_dir' => '', #'search' or 'browse', defaults to 'search' OR - 'redirect' => 'view/table.cgi?', # value of primary key is appended + 'redirect' => 'view/table.cgi?', # value of primary key is appended + OR + 'popup_reload' => 'Momentary success message', #will reload parent window 'error_redirect' => popurl(2).'edit/table.cgi?', #query string appended @@ -60,6 +62,54 @@ Example: ) +%if ( $error ) { +% +% my $edit_ext = $opt{'edit_ext'} || 'html'; +% my $url = $opt{'error_redirect'} || popurl(2)."$table.$edit_ext"; +% if ( length($cgi->query_string) > 1920 ) { #stupid IE 2083 URL limit +% +% my $session = int(rand(4294967296)); #XXX +% my $pref = new FS::access_user_pref({ +% 'usernum' => $FS::CurrentUser::CurrentUser->usernum, +% 'prefname' => "redirect$session", +% 'prefvalue' => $cgi->query_string, +% 'expiration' => time + 3600, #1h? 1m? +% }); +% my $pref_error = $pref->insert; +% if ( $pref_error ) { +% die "FATAL: couldn't even set redirect cookie: $pref_error". +% " attempting to set redirect$session to ". $cgi->query_string."\n"; +% } +% +<% $cgi->redirect("$url?redirect=$session") %> +% +% } else { +% +<% $cgi->redirect("$url?". $cgi->query_string ) %> +% +% } +% +% #different ways of handling success +% +%} elsif ( $opt{'popup_reload'} ) { + + <% include('/elements/header-popup.html', $opt{'popup_reload'} ) %> + + + + + + +%} elsif ( $opt{'redirect'} ) { +% +<% $cgi->redirect( $opt{'redirect'}. $pkeyvalue ) %> +% +%} else { +% +<% $cgi->redirect( popurl(3). ($opt{viewall_dir}||'search'). "/$table.html" ) %> +%} <%once> my $me = 'process.html:'; @@ -162,7 +212,6 @@ if ( !$error && $opt{'process_m2name'} ) { ); } -# XXX print?!?! if ( $error ) { $cgi->param('error', $error); @@ -171,33 +220,6 @@ if ( $error ) { $cgi->param($field, '') } } - my $edit_ext = $opt{'edit_ext'} || 'html'; - my $url = $opt{'error_redirect'} || popurl(2)."$table.$edit_ext"; - if ( length($cgi->query_string) > 1920 ) { #stupid IE 2083 URL limit - - my $session = int(rand(4294967296)); #XXX - my $pref = new FS::access_user_pref({ - 'usernum' => $FS::CurrentUser::CurrentUser->usernum, - 'prefname' => "redirect$session", - 'prefvalue' => $cgi->query_string, - 'expiration' => time + 3600, #1h? 1m? - }); - my $pref_error = $pref->insert; - if ( $pref_error ) { - die "FATAL: couldn't even set redirect cookie: $pref_error". - " attempting to set redirect$session to ". $cgi->query_string."\n"; - } - print $cgi->redirect("$url?redirect=$session"); - } else { - print $cgi->redirect("$url?". $cgi->query_string ); - } -} elsif ( $opt{'redirect'} ) { - print $cgi->redirect( $opt{'redirect'}. $pkeyvalue ); -} else { - print $cgi->redirect( popurl(3). - ( $opt{'viewall_dir'} || 'search' ). - "/$table.html" - ); } diff --git a/httemplate/search/elements/search.html b/httemplate/search/elements/search.html index f3103886b..6e2255d8b 100644 --- a/httemplate/search/elements/search.html +++ b/httemplate/search/elements/search.html @@ -51,7 +51,20 @@ Example: #listref of column labels, #required unless 'query' is an SQL query string # (if not specified the database column names will be used) - 'header' => [ '#', 'Item' ], + 'header' => [ '#', + 'Item', + { 'label' => 'Another Item', + + }, + ], + + #second (smaller) header line, currently only for HTML + 'header2 => [ '#', + 'Item', + { 'label' => 'Another Item', + + }, + ], 'disable_download' => '', # set true to hide the CSV/Excel download links 'disable_nonefound' => '', # set true to disable the "No matching Xs found" @@ -80,19 +93,27 @@ Example: #listref of column footers 'footer' => [], - #listref - each item is the empty string, or a listref of ... - 'links' => - + #listref - each item is the empty string, + # or a listref of link and method name to append, + # or a listref of link and coderef to run and append + # or a coderef that returns such a listref + 'links' => [],` + + #listref - each item is the empty string, + # or a string onClick handler for the corresponding link + # or a coderef that returns string onClick handler + 'link_onclicks' => [], + + #one letter for each column, left/right/center/none + # or pass a listref with full values: [ 'left', 'right', 'center', '' ] + 'align' => 'lrc.', - 'align' => 'lrc.', #one letter for each column, left/right/center/none - # can also pass a listref with full values: - # [ 'left', 'right', 'center', '' ] - - #listrefs... + #listrefs of ( scalars or coderefs ) #currently only HTML, maybe eventually Excel too 'color' => [], 'size' => [], - 'style' => [], + 'style' => [], # or , etc. + 'cell_style' => [], #STYLE= attribute of TR, very HTML-specific... #redirect if there's only one item... # listref of URL base and column name (or method) @@ -381,11 +402,42 @@ Example: <% include('/elements/table-grid.html') %> -% foreach my $header ( @$header ) { - <% $header %> +% my $h2 = 0; +% foreach my $header ( @{ $opt{header} } ) { +% my $label = ref($header) ? $header->{label} : $header; +% my $rowspan = 1; +% my $style = ''; +% if ( $opt{header2} ) { +% if ( !length($opt{header2}->[$h2]) ) { +% $rowspan = 2; +% splice @{ $opt{header2} }, $h2, 1; +% } else { +% $h2++; +% $style = 'STYLE="border-bottom: none"' +% } +% } + + + > + <% $label %> + % } +% if ( $opt{header2} ) { + +% foreach my $header ( @{ $opt{header2} } ) { +% my $label = ref($header) ? $header->{label} : $header; + + <% $label %> + +% } + +% } + % my $bgcolor1 = '#eeeeee'; % my $bgcolor2 = '#ffffff'; % my $bgcolor; @@ -402,11 +454,13 @@ Example: % if ( $opt{'fields'} ) { % -% my $links = $opt{'links'} ? [ @{$opt{'links'}} ] : ''; -% my $aligns = $opt{'align'} ? [ @{$opt{'align'}} ] : ''; -% my $colors = $opt{'color'} ? [ @{$opt{'color'}} ] : []; -% my $sizes = $opt{'size'} ? [ @{$opt{'size'}} ] : []; -% my $styles = $opt{'style'} ? [ @{$opt{'style'}} ] : []; +% my $links = $opt{'links'} ? [ @{$opt{'links'}} ] : ''; +% my $onclicks = $opt{'link_onclicks'} ? [ @{$opt{'link_onclicks'}} ] : []; +% my $aligns = $opt{'align'} ? [ @{$opt{'align'}} ] : ''; +% my $colors = $opt{'color'} ? [ @{$opt{'color'}} ] : []; +% my $sizes = $opt{'size'} ? [ @{$opt{'size'}} ] : []; +% my $styles = $opt{'style'} ? [ @{$opt{'style'}} ] : []; +% my $cstyles = $opt{'cell_style'} ? [ @{$opt{'cell_style'}} ] : []; % % foreach my $field ( % @@ -489,7 +543,14 @@ Example: % my $a = ''; % if ( $links ) { % my $link = shift @$links; -% $link = &{$link}($row) if ref($link) eq 'CODE'; +% $link = &{$link}($row) +% if ref($link) eq 'CODE'; +% +% my $onclick = shift @$onclicks; +% $onclick = &{$onclick}($row) +% if ref($onclick) eq 'CODE'; +% $onclick = qq( onClick="$onclick") if $onclick; +% % if ( $link ) { % my( $url, $method ) = @{$link}; % if ( ref($method) eq 'CODE' ) { @@ -497,7 +558,7 @@ Example: % } else { % $a = $url. $row->$method(); % } -% $a = qq(); +% $a = qq(); % } % } % @@ -520,8 +581,13 @@ Example: % $s = join( '', map "<$_>", split('', $style) ); % $es = join( '', map "", split('', $style) ); % } +% +% my $cstyle = shift @$cstyles; +% $cstyle = &{$cstyle}($row) if ref($cstyle) eq 'CODE'; +% $cstyle = qq(STYLE="$cstyle") +% if $cstyle; - ><% $font %><% $a %><% $s %><% $field %><% $es %><% $a ? '' : '' %><% $font ? '' : '' %> + <% $cstyle %>><% $font %><% $a %><% $s %><% $field %><% $es %><% $a ? '' : '' %><% $font ? '' : '' %> % } % @@ -626,6 +692,8 @@ if ( $opt{'agent_virt'} ) { splice @{ $opt{'color'} }, $pos, 0, ''; splice @{ $opt{'links'} }, $pos, 0, '' #[ 'agent link?', 'agentnum' ] if $opt{'links'}; + splice @{ $opt{'link_onclicks'} }, $pos, 0, '' + if $opt{'link_onclicks'}; } @@ -661,6 +729,8 @@ if ( $opt{'disableable'} ) { sub { shift->disabled ? 'FF0000' : '00CC00'; }; splice @{ $opt{'links'} }, $pos, 0, '' if $opt{'links'}; + splice @{ $opt{'link_onlicks'} }, $pos, 0, '' + if $opt{'link_onlicks'}; } #add show/hide disabled links @@ -728,7 +798,7 @@ unless ( $type =~ /^(csv|\w*\.xls)$/ ) { # run the query -my $header = $opt{header}; +my $header = [ map { ref($_) ? $_->{'label'} : $_ } @{$opt{header}} ]; my $rows; if ( ref($opt{query}) ) { -- 2.11.0