X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=httemplate%2Fsearch%2Freport_tax.cgi;h=120768d3bac52cc7ede603b50c6e216ff8e77274;hb=89cea41d2bd7887a5b6b067ea5fb3f7bfa3b1a26;hp=bcceaf17593ba76ab4c78dc61f29a982ac7ea2ae;hpb=dc313675fc24fa04a619cc980d48de9e4cf2f876;p=freeside.git diff --git a/httemplate/search/report_tax.cgi b/httemplate/search/report_tax.cgi index bcceaf175..120768d3b 100755 --- a/httemplate/search/report_tax.cgi +++ b/httemplate/search/report_tax.cgi @@ -10,31 +10,45 @@ ) ) %> + +Download full results
+as Excel spreadsheet + <% include('/elements/table-grid.html') %> - + Sales - - Rate - - Tax owed + + Rate + + Tax owed % unless ( $cgi->param('show_taxclasses') ) { - Tax invoiced + Tax invoiced + + Tax credited + + Tax collected % } - Total - - Non-taxable
(tax-exempt customer) - - Non-taxable
(tax-exempt package) - - Non-taxable
(monthly exemption) - - Taxable + Total + + Non-taxable + + Non-taxable + + Non-taxable + + Taxable + + + + (tax-exempt customer) + (tax-exempt package) + (monthly exemption) % my $bgcolor1 = '#eeeeee'; @@ -118,6 +132,15 @@ <% &$money_sprintf( $region->{'tax'} ) %> + <<%$tdh%>> - + <<%$tdh%> ALIGN="right"> + <% &$money_sprintf( $region->{'credit'} ) %> + + <<%$tdh%>> = + <<%$tdh%> ALIGN="right"> + <% &$money_sprintf( $region->{'tax'} - $region->{'credit'} ) %> + % } @@ -132,6 +155,10 @@ Tax invoiced + + Tax credited + + Tax collected % #some false laziness w/above @@ -154,6 +181,12 @@ % $bgcolor = $bgcolor1; % } % my $td = qq(TD CLASS="grid" BGCOLOR="$bgcolor"); +% my $tdh = qq(TD CLASS="grid" BGCOLOR="$bgcolor"); +% +% #? +% my $invlink = $region->{'url_param_inv'} +% ? ';'. $region->{'url_param_inv'} +% : $link; <<%$td%>><% $region->{'label'} %> @@ -161,6 +194,15 @@ <% &$money_sprintf( $region->{'tax'} ) %> + <<%$td%>> - + <<%$tdh%> ALIGN="right"> + <% &$money_sprintf( $region->{'credit'} ) %> + + <<%$td%>> = + <<%$tdh%> ALIGN="right"> + <% &$money_sprintf( $region->{'tax'} - $region->{'credit'} ) %> + % } @@ -178,6 +220,15 @@ <% &$money_sprintf( $tot_tax ) %> + <<%$td%>> - + <<%$td%> ALIGN="right"> + <% &$money_sprintf( $tot_credit ) %> + + <<%$td%>> = + <<%$td%> ALIGN="right"> + <% &$money_sprintf( $tot_tax - $tot_credit ) %> + @@ -224,7 +275,13 @@ sub gotcust { my $table = shift; my $prefix = @_ ? shift : ''; " - ( $table.${prefix}county = cust_main_county.county + ( $table.district = cust_main_county.district + OR cust_main_county.district = '' + OR cust_main_county.district IS NULL ) + AND ( $table.${prefix}city = cust_main_county.city + OR cust_main_county.city = '' + OR cust_main_county.city IS NULL ) + AND ( $table.${prefix}county = cust_main_county.county OR cust_main_county.county = '' OR cust_main_county.county IS NULL ) AND ( $table.${prefix}state = cust_main_county.state @@ -278,6 +335,7 @@ if ( $conf->exists('tax-pkg_address') ) { } my $out = 'Out of taxable region(s)'; +# these are actually tax labels, not regions my %regions = (); foreach my $r ( qsearch({ 'table' => 'cust_main_county', @@ -287,15 +345,17 @@ foreach my $r ( qsearch({ 'table' => 'cust_main_county', { #warn $r->county. ' '. $r->state. ' '. $r->country. "\n"; + # set up a %regions entry for this region's tax label my $label = getlabel($r); $regions{$label}->{'label'} = $label; $regions{$label}->{$_} = $r->$_() for (qw( county state country )); #taxname? + my @url_param = qw( county state country taxname ); + push @url_param, 'city' if $cgi->param('show_cities') && $r->city(); + $regions{$label}->{'url_param'} = - join(';', map "$_=".uri_escape($r->$_()), - qw( county state country taxname ) - ); + join(';', map "$_=".uri_escape($r->$_()), @url_param ); my @param = @base_param; my $mywhere = $where; @@ -311,53 +371,53 @@ foreach my $r ( qsearch({ 'table' => 'cust_main_county', } else { - $regions{$label}->{'url_param'} .= ';taxclassNULL=1' - if $cgi->param('show_taxclasses'); - + # SQL for "taxclass doesn't match any other tax in the region" my $same_sql = $r->sql_taxclass_sameregion; $mywhere .= " AND $same_sql" if $same_sql; + $regions{$label}->{'url_param'} .= ';taxclassNULL=1' + if $cgi->param('show_taxclasses') + || $same_sql; + } + # FROM cust_bill_pkg JOIN (whatever is needed to determine tax location) + # WHERE (matches tax location and agentnum and taxclass) + # takes parameters in @base_param, plus taxclass if there is one my $fromwhere = "$from_join_cust_pkg $mywhere"; # AND payby != 'COMP' "; -# my $label = getlabel($r); -# $regions{$label}->{'label'} = $label; - my $nottax = 'pkgnum != 0'; - ## calculate total for this region + ## calculate total of sales (non-tax line items) for this region my $t_sql = "SELECT SUM(cust_bill_pkg.setup+cust_bill_pkg.recur) $fromwhere AND $nottax"; my $t = scalar_sql($r, \@param, $t_sql); $regions{$label}->{'total'} += $t; - #if ( $label eq $out ) # && $t ) { - # warn "adding $t for ". - # join('/', map $r->$_, qw( taxclass county state country ) ). "\n"; - # #warn $t_sql if $r->state eq 'FL'; - #} + #$regions{$label}->{subtotals}->{$r->taxnum} = $t; #useful debug ## calculate customer-exemption for this region -## my $taxable = $t; - -# my($taxable, $x_cust) = (0, 0); -# foreach my $e ( grep { $r->get($_.'tax') !~ /^Y/i } -# qw( cust_bill_pkg.setup cust_bill_pkg.recur ) ) { -# $taxable += scalar_sql($r, \@param, -# "SELECT SUM($e) $fromwhere AND $nottax AND ( tax != 'Y' OR tax IS NULL )" -# ); -# -# $x_cust += scalar_sql($r, \@param, -# "SELECT SUM($e) $fromwhere AND $nottax AND tax = 'Y'" -# ); -# } + #false laziness -ish w/report_tax.cgi + my $cust_exempt; + if ( $r->taxname ) { + my $q_taxname = dbh->quote($r->taxname); + $cust_exempt = + "( tax = 'Y' + OR EXISTS ( SELECT 1 FROM cust_main_exemption + WHERE cust_main_exemption.custnum = cust_main.custnum + AND cust_main_exemption.taxname = $q_taxname + ) + ) + "; + } else { + $cust_exempt = " tax = 'Y' "; + } my $x_cust = scalar_sql($r, \@param, "SELECT SUM(cust_bill_pkg.setup+cust_bill_pkg.recur) - $fromwhere AND $nottax AND tax = 'Y' " + $fromwhere AND $nottax AND $cust_exempt " ); $regions{$label}->{'exempt_cust'} += $x_cust; @@ -414,10 +474,12 @@ foreach my $r ( qsearch({ 'table' => 'cust_main_county', } else { $regions{$label}->{'rate'} = $r->tax.'%'; } - } +#warn Dumper(\%regions); +# $regions{$label} now contains 'total', 'exempt_cust', 'exempt_pkg', +# 'exempt_monthly', summed over each set of regions with the same label. -my $distinct = "country, state, county, +my $distinct = "country, state, county, city, district, CASE WHEN taxname IS NULL THEN '' ELSE taxname END AS taxname"; my $taxclass_distinct = #a little bit unsure of this part... test? @@ -447,11 +509,28 @@ if ( $conf->exists('tax-pkg_address') ) { $taxwhere =~ s/cust_pkg\.locationnum/cust_bill_pkg_tax_location.locationnum/g; } +my $creditfromwhere = $taxfromwhere. + " JOIN cust_credit_bill_pkg USING (billpkgnum"; +$creditfromwhere .= " ,billpkgtaxlocationnum" + if $conf->exists('tax-pkg_address'); +$creditfromwhere .= ")"; + $taxfromwhere .= " $taxwhere "; #AND payby != 'COMP' "; -my @taxparam = @base_param; +$creditfromwhere .= " $taxwhere AND billpkgtaxratelocationnum IS NULL"; #AND payby != 'COMP' "; #should i be a cust_main_county method or something -#need to pass in $taxfromwhere & @taxparam??? +# yes. yes, you should. + +# $taxfromwhere: Most of a query to find cust_bill_pkg records linked to a +# customer matching a given state/county/city/district (and within the date +# range for the report). +# @base_param: A list of the fields from cust_main_county to use as parameters. + +# $_taxamount_sub: Takes a cust_main_county and returns the sum of taxes billed +# within the report period for all customers located in that county. If +# the cust_main_county has a taxname, limits to taxes with that name; otherwise +# includes all line items with pkgnum = 0 and description either 'Tax' or empty. + my $_taxamount_sub = sub { my $r = shift; @@ -464,7 +543,24 @@ my $_taxamount_sub = sub { my $sql = "SELECT SUM(cust_bill_pkg.setup+cust_bill_pkg.recur) ". " $taxfromwhere AND cust_bill_pkg.pkgnum = 0 $named_tax"; - scalar_sql($r, \@taxparam, $sql ); + scalar_sql($r, [ @base_param ], $sql ); +}; + +# $_creditamount_sub: As above, but returns the sum of credits applied + +my $_creditamount_sub = sub { + my $r = shift; + + #match itemdesc if necessary! + my $named_tax = + $r->taxname + ? 'AND itemdesc = '. dbh->quote($r->taxname) + : "AND ( itemdesc IS NULL OR itemdesc = '' OR itemdesc = 'Tax' )"; + + my $sql = "SELECT SUM(cust_credit_bill_pkg.amount) ". + " $creditfromwhere AND cust_bill_pkg.pkgnum = 0 $named_tax"; + + scalar_sql($r, [ @base_param ], $sql ); }; #tax-report_groups filtering @@ -487,6 +583,7 @@ my $group_test = sub { }; my $tot_tax = 0; +my $tot_credit = 0; #foreach my $label ( keys %regions ) { foreach my $r ( qsearch(\%qsearch) ) { @@ -505,6 +602,13 @@ foreach my $r ( qsearch(\%qsearch) ) { $regions{$label}->{'tax'} += $x; $tot_tax += $x unless $cgi->param('show_taxclasses'); + ## calculate credit for this region + + $x = &{$_creditamount_sub}($r); + + $regions{$label}->{'credit'} += $x; + $tot_credit += $x unless $cgi->param('show_taxclasses'); + } my %base_regions = (); @@ -525,6 +629,14 @@ if ( $cgi->param('show_taxclasses') ) { $base_regions{$base_label}->{'tax'} += $x; $tot_tax += $x; + + ## calculate credit for this region + + $x = &{$_creditamount_sub}($r); + + $base_regions{$base_label}->{'credit'} += $x; + $tot_credit += $x; + } } @@ -537,7 +649,7 @@ my @regions = keys %regions; #calculate totals my( $total, $tot_taxable, $tot_owed ) = ( 0, 0, 0 ); -my( $exempt_cust, $exempt_pkg, $exempt_monthly ) = ( 0, 0, 0 ); +my( $exempt_cust, $exempt_pkg, $exempt_monthly, $tot_credit ) = ( 0, 0, 0, 0 ); my %taxclasses = (); my %county = (); my %state = (); @@ -549,6 +661,7 @@ foreach (@regions) { $exempt_cust += $regions{$_}->{'exempt_cust'}; $exempt_pkg += $regions{$_}->{'exempt_pkg'}; $exempt_monthly += $regions{$_}->{'exempt_monthly'}; + $tot_credit += $regions{$_}->{'credit'}; $taxclasses{$regions{$_}->{'taxclass'}} = 1 if $regions{$_}->{'taxclass'}; $county{$regions{$_}->{'county'}} = 1; @@ -604,6 +717,7 @@ push @regions, { 'rate' => '', 'owed' => $tot_owed, 'tax' => $tot_tax, + 'credit' => $tot_credit, }; #-- @@ -620,8 +734,10 @@ sub getlabel { my $label; if ( $r->tax == 0 - && ! scalar( qsearch('cust_main_county', { 'state' => $r->state, + && ! scalar( qsearch('cust_main_county', { 'district'=> $r->district, + 'city' => $r->city, 'county' => $r->county, + 'state' => $r->state, 'country' => $r->country, 'tax' => { op=>'>', value=>0 }, } @@ -632,14 +748,16 @@ sub getlabel { #kludge to avoid "will not stay shared" warning my $out = 'Out of taxable region(s)'; $label = $out; -# } elsif ( $r->taxname && count_taxname($r->taxname) == 1 ) { -# $label = $r->taxname; -## $regions{$label}->{'taxname'} = $label; -## push @{$regions{$label}->{$_}}, $r->$_() foreach qw( county state country ); } else { $label = $r->country; $label = $r->state.", $label" if $r->state; $label = $r->county." county, $label" if $r->county; + if ( $cgi->param('show_cities') and $r->city ) { + $label = $r->city . ", $label"; + if ( $cgi->param('show_districts') and $r->district ) { + $label = '#' . $r->district . ", $label"; + } + } $label = "$label (". $r->taxclass. ")" if $r->taxclass && $cgi->param('show_taxclasses') @@ -676,5 +794,6 @@ $dateagentlink .= ';agentnum='. $cgi->param('agentnum') if length($agentname); my $baselink = $p. "search/cust_bill_pkg.cgi?$dateagentlink"; my $exemptlink = $p. "search/cust_tax_exempt_pkg.cgi?$dateagentlink"; +my $creditlink = $p. "search/cust_credit_bill_pkg.html?$dateagentlink";