- if ( exists $this_has_tax->{ $tot_id } ) {
- warn "calculating tax on tax: taxnum ".$tot->taxnum." on $taxnum\n"
- if $DEBUG;
- my @taxlines = $tot->taxline(
- $this_has_tax->{ $tax_id }, # the first-stage tax
- 'custnum' => $self->custnum,
- 'invoice_time' => $invoice_time,
- );
- next if (!@taxlines); # it didn't apply after all
- if (!ref($taxlines[0])) {
- warn "error evaluating $tot_id TOT on custnum ".
- $self->custnum."\n";
- return $taxlines[0];
- }
- foreach my $taxline (@taxlines) {
- push @{ $taxname{ $taxline->itemdesc } }, $taxline;
- }
- } # if $has_tax
- } # foreach my $tot (tax-on-tax rate definition)
- } # foreach $taxnum (first-tier rate definition)
+ # Calculate ToT separately for each taxable item and class, and only
+ # if _that class on the item_ is already taxed under the ToT. This is
+ # counterintuitive.
+ # See RT#5243 and RT#36380.
+ foreach my $tot (@tot) {
+ my $totnum = $tot->taxnum;
+ warn "checking taxnum $totnum which we call ". $tot->taxname ."\n"
+ if $DEBUG > 2;
+ # note: if the _null class_ on this item is taxed under the ToT,
+ # then this specific class is taxed also (because null class
+ # includes all classes) and so ToT is applicable.
+ if (
+ exists $this_class_has_tax->{ $totnum }
+ or exists $this_has_tax->{''}{ $totnum }
+ ) {
+
+ warn "calculating tax on tax: taxnum $totnum on $taxnum\n"
+ if $DEBUG;
+ my @taxlines = $tot->taxline(
+ $this_class_has_tax->{ $taxnum }, # the first-stage tax
+ 'custnum' => $custnum,
+ 'invoice_time' => $invoice_time,
+ );
+ next if (!@taxlines); # it didn't apply after all
+ if (!ref($taxlines[0])) {
+ warn "error evaluating taxnum $totnum TOT on custnum $custnum\n";
+ return $taxlines[0];
+ }
+ foreach my $taxline (@taxlines) {
+ push @{ $taxname{ $taxline->itemdesc } }, $taxline;
+ }
+ } # if $has_tax
+ } # foreach my $tot (tax-on-tax rate definition)
+ } # foreach $taxnum (first-tier rate definition)
+ } # foreach $charge_class