-# if show_taxclasses is on, %base_regions will contain the same data
-# as %regions, but with taxclasses merged together (and ignoring report_group
-# filtering).
-my (%regions, %base_regions);
-my $tot_tax = 0;
-my $tot_credit = 0;
-
-my @loc_params = qw(country state county);
-push @loc_params, 'city' if $cgi->param('show_cities');
-push @loc_params, 'district' if $cgi->param('show_districts');
-
-foreach my $r ( qsearch({ 'table' => 'cust_main_county', })) {
- my $taxnum = $r->taxnum;
- # set up a %regions entry for this region's tax label
- my $label = $r->label(%label_opt);
- next if $label eq $out;
- $regions{$label} ||= { label => $label };
-
- $regions{$label}->{$_} = $r->get($_) foreach @loc_params;
- $regions{$label}->{taxnums} ||= [];
- push @{ $regions{$label}->{taxnums} }, $r->taxnum;
-
- my %x; # keys are data items (like 'tax', 'exempt_cust', etc.)
- foreach my $k (keys %data) {
- next unless exists($data{$k}->{$taxnum});
- $x{$k} = $data{$k}->{$taxnum};
- $regions{$label}->{$k} += $x{$k};
- if ( $k eq 'taxable' or $k =~ /^exempt/ ) {
- $regions{$label}->{'sales'} += $x{$k};
+my @pkgclasses;
+if ($with_pkgclass) {
+ @pkgclasses = qsearch('pkg_class', {});
+ push @pkgclasses, FS::pkg_class->new({
+ classnum => '0',
+ classname => 'Unclassified',
+ });
+} else {
+ @pkgclasses = ( FS::pkg_class->new({
+ classnum => '',
+ classname => '',
+ }) );
+}
+my %pkgclass_data;
+
+foreach my $class (@pkgclasses) {
+ my $classnum = $class->classnum;
+ my $classname = $class->classname;
+
+ # if show_taxclasses is on, %base_regions will contain the same data
+ # as %regions, but with taxclasses merged together (and ignoring report_group
+ # filtering).
+ my (%regions, %base_regions);
+
+ my @loc_params = qw(country state county);
+ push @loc_params, 'city' if $cgi->param('show_cities');
+ push @loc_params, 'district' if $cgi->param('show_districts');
+
+ foreach my $r ( qsearch({ 'table' => 'cust_main_county', })) {
+ my $taxnum = $r->taxnum;
+ # set up a %regions entry for this region's tax label
+ my $label = $r->label(%label_opt);
+ next if $label eq $out;
+ $regions{$label} ||= { label => $label };
+
+ $regions{$label}->{$_} = $r->get($_) foreach @loc_params;
+ $regions{$label}->{taxnums} ||= [];
+ push @{ $regions{$label}->{taxnums} }, $r->taxnum;
+
+ my %x; # keys are data items (like 'tax', 'exempt_cust', etc.)
+ foreach my $k (keys %data) {
+ next unless exists($data{$k}{$classnum}{$taxnum});
+ $x{$k} = $data{$k}{$classnum}{$taxnum};
+ $regions{$label}{$k} += $x{$k};
+ if ( $k eq 'taxable' or $k =~ /^exempt/ ) {
+ $regions{$label}->{'sales'} += $x{$k};
+ }