1 <% include( 'elements/browse.html',
2 'title' => "Tax Rates $title",
3 'name_singular' => 'tax rate',
4 'menubar' => \@menubar,
5 'html_init' => $html_init,
9 'order_by' => 'ORDER BY geocode, taxclassnum',
10 'extra_sql' => $extra_sql,
12 'count_query' => $count_query,
14 'header2' => \@header2,
18 'cell_style' => \@cell_style,
20 'link_onclicks' => \@link_onclicks,
25 my $conf = new FS::Conf;
26 my $money_char = $conf->config('money_char') || '$';
31 my $units = $tax_rate->unittype_name;
32 $units =~ s/ / /g;
36 ($tax_rate->tax * 100). '% <FONT SIZE="-1">(edit)</FONT>'
37 if $tax_rate->tax > 0 || $tax_rate->taxbase > 0;
39 ($tax_rate->excessrate * 100). '% <FONT SIZE="-1">(edit)</FONT>'
40 if $tax_rate->excessrate > 0;
42 $money_char. $tax_rate->fee.
43 qq! per $units<FONT SIZE="-1">(edit)</FONT>!
44 if $tax_rate->fee > 0 || $tax_rate->feebase > 0;
46 $money_char. $tax_rate->excessfee.
47 qq! per $units<FONT SIZE="-1">(edit)</FONT>!
48 if $tax_rate->excessfee > 0;
51 [ map [ {'data'=>$_} ], @rate ];
57 my $maxtype = $tax_rate->maxtype_name;
58 $maxtype =~ s/ / /g;
60 my $units = $tax_rate->unittype_name;
61 $units =~ s/ / /g;
65 sprintf("$money_char%.2f %s", $tax_rate->taxbase, $maxtype )
66 if $tax_rate->taxbase > 0;
68 sprintf("$money_char%.2f tax", $tax_rate->taxmax )
69 if $tax_rate->taxmax > 0;
71 $tax_rate->feebase. " $units". ($tax_rate->feebase == 1 ? '' : 's')
72 if $tax_rate->feebase > 0;
74 $tax_rate->feemax. " $units". ($tax_rate->feebase == 1 ? '' : 's')
75 if $tax_rate->feemax > 0;
77 push @limit, 'Excluding setup fee'
78 if $tax_rate->setuptax =~ /^Y$/i;
80 push @limit, 'Excluding recurring fee'
81 if $tax_rate->recurtax =~ /^Y$/i;
83 [ map [ {'data'=>$_} ], @limit ];
88 my $cell_style_sub = sub {
90 if ( $oldrow ne $row ) {
92 if ( $oldrow->country ne $row->country ) {
93 $cell_style = 'border-top:1px solid #000000';
94 } elsif ( $oldrow->state ne $row->state ) {
95 $cell_style = 'border-top:1px solid #cccccc'; #default?
96 } elsif ( $oldrow->state eq $row->state ) {
97 #$cell_style = 'border-top:dashed 1px dark gray';
98 $cell_style = 'border-top:1px dashed #cccccc';
106 my $select_link = [ 'javascript:void(0);', sub { ''; } ];
108 my $select_onclick = sub {
110 my $taxnum = $row->taxnum;
111 my $color = '#333399';
112 qq!overlib( OLiframeContent('${p}edit/tax_rate.html?$taxnum', 540, 620, 'edit_tax_rate_popup' ), CAPTION, 'Edit tax rate', STICKY, AUTOSTATUSCAP, MIDX, 0, MIDY, 0, DRAGGABLE, CLOSECLICK, BGCOLOR, '$color', CGCOLOR, '$color' ); return false;!;
119 unless $FS::CurrentUser::CurrentUser->access_right('Configuration');
124 my $data_vendor = '';
125 if ( $cgi->param('data_vendor') =~ /^(\w+)$/ ) {
127 $title = "$data_vendor";
129 $cgi->delete('data_vendor');
132 if ( $cgi->param('geocode') =~ /^(\w+)$/ ) {
134 $title = " geocode $geocode";
136 $cgi->delete('geocode');
138 $title = " for $title" if $title;
140 my $taxclassnum = '';
141 if ( $cgi->param('taxclassnum') =~ /^(\d+)$/ ) {
143 my $tax_class = qsearchs('tax_class', {'taxclassnum' => $taxclassnum});
145 $title .= " for ". $tax_class->taxclass.
146 " (". $tax_class->description. ") tax class";
151 $cgi->delete('taxclassnum');
154 if ( $cgi->param('tax_type') =~ /^(\d+)$/ );
156 if ( $cgi->param('tax_cat') =~ /^(\d+)$/ );
158 my @taxclassnum = ();
159 if ($tax_type || $tax_cat ) {
160 my $compare = "LIKE '". ( $tax_type || "%" ). ":". ( $tax_cat || "%" ). "'";
161 $compare = "= '$tax_type:$tax_cat'" if ($tax_type && $tax_cat);
163 qsearch({ 'table' => 'tax_class',
165 'extra_sql' => "WHERE taxclass $compare",
168 @taxclassnum = map { $_->taxclassnum } @tax_class;
169 $tax_class[0]->description =~ /^(.*):(.*)/;
171 $title .= " $tax_type ($1) tax type" if $tax_type;
172 $title .= " and" if ($tax_type && $tax_cat);
173 $title .= " $tax_cat ($2) tax category" if $tax_cat;
179 $cgi->delete('tax_type');
180 $cgi->delete('tax_cat');
183 if ( $geocode || $taxclassnum ) {
184 push @menubar, 'View all tax rates' => $p.'browse/tax_rate.cgi';
187 $cgi->param('dummy', 1);
189 #restore this so pagination works
190 $cgi->param('data_vendor', $data_vendor) if $data_vendor;
191 $cgi->param('geocode', $geocode) if $geocode;
192 $cgi->param('taxclassnum', $taxclassnum ) if $taxclassnum;
193 $cgi->param('tax_type', $tax_type ) if $tax_type;
194 $cgi->param('tax_cat', $tax_cat ) if $tax_cat;
198 if ( $data_vendor ) {
199 $extra_sql .= ' WHERE data_vendor = '. dbh->quote($data_vendor);
203 $extra_sql .= ( $extra_sql =~ /WHERE/i ? ' AND ' : ' WHERE ' ).
204 ' geocode LIKE '. dbh->quote($geocode.'%');
207 if ( $taxclassnum ) {
208 $extra_sql .= ( $extra_sql =~ /WHERE/i ? ' AND ' : ' WHERE ' ).
209 ' taxclassnum = '. dbh->quote($taxclassnum);
212 if ( @taxclassnum ) {
213 $extra_sql .= ( $extra_sql =~ /WHERE/i ? ' AND ' : ' WHERE ' ).
214 join(' OR ', map { " taxclassnum = $_ " } @taxclassnum );
217 my $count_query = "SELECT COUNT(*) FROM tax_rate $extra_sql";
221 my @header = ( 'Location Code', );
222 my @header2 = ( '', );
224 my @link_onclicks = ( '', );
235 push @header, qq!Tax class (<A HREF="${p}edit/tax_class.html">add new</A>)!;
236 push @header2, '(per-tax classification)';
237 push @fields, 'taxclass_description';
238 push @color, '000000';
240 push @link_onclicks, '';
243 push @header, 'Tax name',
248 push @header2, '(printed on invoices)',
254 sub { shift->taxname || 'Tax' },
260 sub { shift->taxname ? '000000' : '666666' },
261 sub { shift->tax ? '000000' : '666666' },
267 my @cell_style = map $cell_style_sub, (1..scalar(@header));
269 push @links, '', $select_link, '';
270 push @link_onclicks, '', $select_onclick, '';
275 <SCRIPT TYPE="text/javascript" SRC="${fsurl}elements/overlibmws.js"></SCRIPT>
276 <SCRIPT TYPE="text/javascript" SRC="${fsurl}elements/overlibmws_iframe.js"></SCRIPT>
277 <SCRIPT TYPE="text/javascript" SRC="${fsurl}elements/overlibmws_draggable.js"></SCRIPT>
278 <SCRIPT TYPE="text/javascript" SRC="${fsurl}elements/iframecontentmws.js"></SCRIPT>
286 <TD><SELECT NAME="data_vendor" onChange="this.form.submit()">
289 my $sql = "SELECT DISTINCT data_vendor FROM tax_rate ORDER BY data_vendor";
291 my $sth = $dbh->prepare($sql) or die $dbh->errstr;
292 $sth->execute or die $sth->errstr;
293 for (['(choose data vendor)'], @{$sth->fetchall_arrayref}) {
294 $html_init .= '<OPTION VALUE="'. $_->[0]. '"'.
295 ($_->[0] eq $data_vendor ? " SELECTED" : "").
301 <TD><INPUT NAME="geocode" TYPE="text" SIZE="12" VALUE="$geocode"></TD>
304 <TD><INPUT NAME="taxclassnum" TYPE="text" SIZE="12" VALUE="$taxclassnum"></TD>
305 <TD><INPUT TYPE="submit" VALUE="Filter by tax_class"></TD>
308 <!-- cch specific -->
309 <TD><SELECT NAME="tax_type" onChange="this.form.submit()">
312 $sql = "SELECT DISTINCT ".
313 "substring(taxclass from 1 for position(':' in taxclass)-1),".
314 "substring(description from 1 for position(':' in description)-1) ".
315 "FROM tax_class WHERE data_vendor='cch' ORDER BY 2";
317 $sth = $dbh->prepare($sql) or die $dbh->errstr;
318 $sth->execute or die $sth->errstr;
319 for (['', '(choose tax type)'], @{$sth->fetchall_arrayref}) {
320 $html_init .= '<OPTION VALUE="'. $_->[0]. '"'.
321 ($_->[0] eq $tax_type ? " SELECTED" : "").
328 <TD><SELECT NAME="tax_cat" onChange="this.form.submit()">
331 $sql = "SELECT DISTINCT ".
332 "substring(taxclass from position(':' in taxclass)+1),".
333 "substring(description from position(':' in description)+1) ".
334 "from tax_class WHERE data_vendor='cch' ORDER BY 2";
336 $sth = $dbh->prepare($sql) or die $dbh->errstr;
337 $sth->execute or die $sth->errstr;
338 for (['', '(choose tax category)'], @{$sth->fetchall_arrayref}) {
339 $html_init .= '<OPTION VALUE="'. $_->[0]. '"'.
340 ($_->[0] eq $tax_cat ? " SELECTED" : "").
350 <TD><INPUT TYPE="submit" VALUE="Filter by geocode"></TD>