X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2FTaxEngine%2Finternal.pm;h=db7010c18f7136f105acccd676f0719da89c11bc;hb=f235a64b4e96e8d613fb3ecdd3acc7f65f9f291d;hp=d2a5d7fa6be3d6699bcf4bb23a73ffaa4b96ab18;hpb=3cdd4af468c2c93e1fe4ab6a0ac95537aca5068e;p=freeside.git diff --git a/FS/FS/TaxEngine/internal.pm b/FS/FS/TaxEngine/internal.pm index d2a5d7fa6..db7010c18 100644 --- a/FS/FS/TaxEngine/internal.pm +++ b/FS/FS/TaxEngine/internal.pm @@ -66,7 +66,7 @@ sub taxline { my $taxnum = $tax_object->taxnum; my $exemptions = $self->{exemptions}->{$taxnum} ||= []; - my $taxable_cents = 0; + my $taxable_total = 0; my $tax_cents = 0; my $round_per_line_item = $conf->exists('tax-round_per_line_item'); @@ -244,6 +244,7 @@ sub taxline { year => $year, month => $mon, }); + $taxable_charged -= $addl; } # if they're using multiple months of exemption for a multi-month @@ -257,16 +258,31 @@ sub taxline { } } # if exempt_amount - $_->taxnum($tax_object->taxnum) foreach @new_exemptions; - # attach them to the line item - push @{ $cust_bill_pkg->cust_tax_exempt_pkg }, @new_exemptions; + foreach my $ex (@new_exemptions) { + + $ex->set('taxnum', $taxnum); + + if ( $cust_bill_pkg->billpkgnum ) { + # the exempted item is already inserted (it should be, these days) so + # insert the exemption record now: + $ex->set('billpkgnum', $cust_bill_pkg->billpkgnum); + my $error = $ex->insert; + return "inserting tax exemption record: $error" if $error; + + } else { + # defer it until the item is inserted + push @{ $cust_bill_pkg->cust_tax_exempt_pkg }, $ex; + } + } + + # and remember we've used the exemption push @existing_exemptions, @new_exemptions; $taxable_charged = sprintf( "%.2f", $taxable_charged); next if $taxable_charged == 0; - my $this_tax_cents = $taxable_charged * $self->tax; + my $this_tax_cents = $taxable_charged * $tax_object->tax; if ( $round_per_line_item ) { # Round the tax to the nearest cent for each line item, instead of # across the whole invoice. @@ -286,15 +302,17 @@ sub taxline { }); push @tax_links, $location; - $taxable_cents += $taxable_charged; + $taxable_total += $taxable_charged; $tax_cents += $this_tax_cents; } #foreach $cust_bill_pkg - # calculate tax and rounding error for the whole group - my $extra_cents = sprintf('%.2f', $taxable_cents * $tax_object->tax / 100) - * 100 - $tax_cents; - # make sure we have an integer - $extra_cents = sprintf('%.0f', $extra_cents); + # calculate tax and rounding error for the whole group: total taxable + # amount times tax rate (as cents per dollar), minus the tax already + # charged + # and force 0.5 to round up + my $extra_cents = sprintf('%.0f', + ($taxable_total * $tax_object->tax) - $tax_cents + 0.00000001 + ); # if we're rounding per item, then ignore that and don't distribute any # extra cents.