+ # ensure that it is a tax:
+ push @where, 'cust_bill_pkg.pkgnum = 0',
+ 'cust_bill_pkg.feepart IS NULL';
+
+ # We MUST NOT join cust_bill_pkg to any table that it's 1:many to.
+ # Otherwise we get duplication of the cust_bill_pkg records,
+ # inaccurate totals, nonsensical paging behavior, etc.
+ # We CAN safely join it to a subquery that has unique billpkgnums, and
+ # that's what we'll do.
+
+ my $tax_subquery;
+ my @tax_where;
+
+ # tax location when using tax_rate_location
+ if ( $cgi->param('vendortax') ) {
+
+ $tax_subquery = '
+ SELECT billpkgnum, SUM(amount) as tax_total
+ FROM cust_bill_pkg_tax_rate_location AS tax
+ JOIN tax_rate_location USING (taxratelocationnum)
+ ';
+ foreach (qw( state county city locationtaxid)) {
+ if ( scalar($cgi->param($_)) ) {
+ my $place = dbh->quote( $cgi->param($_) );
+ push @tax_where, "tax_rate_location.$_ = $place";
+ }
+ }
+
+ } else { # the internal-tax case
+
+ my $tax_select = 'SELECT tax.billpkgnum, SUM(tax.amount) as tax_total';
+ my $tax_from = ' FROM cust_bill_pkg_tax_location AS tax JOIN cust_main_county USING (taxnum)';
+
+ # package classnum
+ if ( grep { $_ eq 'classnum' } $cgi->param ) {
+ my @classnums = grep /^\d*$/, $cgi->param('classnum');
+ $tax_from .= '
+ JOIN cust_bill_pkg AS taxed_item
+ ON (tax.taxable_billpkgnum = taxed_item.billpkgnum)
+ LEFT JOIN cust_pkg AS taxed_pkg ON (taxed_item.pkgnum = taxed_pkg.pkgnum)
+ LEFT JOIN part_pkg AS taxed_part_pkg ON (taxed_pkg.pkgpart = taxed_part_pkg.pkgpart)
+ LEFT JOIN part_fee AS taxed_part_fee ON (taxed_item.feepart = taxed_part_fee.feepart)
+ ';
+ push @tax_where,
+ "COALESCE(taxed_part_pkg.classnum, taxed_part_fee.classnum,0) IN ( ".
+ join(',', @classnums ).
+ ' )'
+ if @classnums;
+ }
+
+ # taxclass
+ if ( $cgi->param('taxclassNULL') ) {
+ push @tax_where, 'cust_main_county.taxclass IS NULL';
+ }
+
+ # taxname
+ if ( $cgi->param('taxnameNULL') ) {
+ push @tax_where, 'cust_main_county.taxname IS NULL OR '.
+ 'cust_main_county.taxname = \'Tax\'';
+ } elsif ( $cgi->param('taxname') ) {
+ push @tax_where, 'cust_main_county.taxname = '.
+ dbh->quote($cgi->param('taxname'));
+ }
+
+ # itemdesc, for breakdown from the vendor tax report
+ # (is this even used? vendor tax report shouldn't use cust_bill_pkg.cgi)
+ if ( $cgi->param('itemdesc') ) {
+ if ( $cgi->param('itemdesc') eq 'Tax' ) {
+ push @where, "($itemdesc = 'Tax' OR $itemdesc is null)";
+ } else {
+ push @where, "$itemdesc = ". dbh->quote($cgi->param('itemdesc'));
+ }
+ }
+
+ # specific taxnums (the usual way)
+ if ( $cgi->param('taxnum') =~ /^([\d,]+)$/) {
+ push @tax_where, "cust_main_county.taxnum IN ($1)";
+ }
+
+ $tax_subquery = "$tax_select $tax_from";
+
+ } # end of internal-tax case
+
+ if (@tax_where) {
+ $tax_subquery .= '
+ WHERE ' . join(' AND ', map "($_)", @tax_where);
+ }
+ $tax_subquery .= ' GROUP BY tax.billpkgnum ';
+
+ # now join THAT into the main report
+ # (inner join, so that tax line items that don't match the tax_where
+ # conditions don't appear in the output.)