X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2FTaxEngine%2Finternal.pm;h=d2a5d7fa6be3d6699bcf4bb23a73ffaa4b96ab18;hb=3cdd4af468c2c93e1fe4ab6a0ac95537aca5068e;hp=99535ad38161bd669bb73eeec24f97a9bd732a58;hpb=0fda4498e5b48587090b03d40ea97fec1e024385;p=freeside.git diff --git a/FS/FS/TaxEngine/internal.pm b/FS/FS/TaxEngine/internal.pm index 99535ad38..d2a5d7fa6 100644 --- a/FS/FS/TaxEngine/internal.pm +++ b/FS/FS/TaxEngine/internal.pm @@ -3,6 +3,12 @@ package FS::TaxEngine::internal; use strict; use base 'FS::TaxEngine'; use FS::Record qw(dbh qsearch qsearchs); +use FS::Conf; +use vars qw( $conf ); + +FS::UID->install_callback(sub { + $conf = FS::Conf->new; +}); =head1 SUMMARY @@ -60,10 +66,11 @@ sub taxline { my $taxnum = $tax_object->taxnum; my $exemptions = $self->{exemptions}->{$taxnum} ||= []; - my $name = $tax_object->taxname || 'Tax'; my $taxable_cents = 0; my $tax_cents = 0; + my $round_per_line_item = $conf->exists('tax-round_per_line_item'); + my $cust_main = $self->{cust_main}; my $custnum = $cust_main->custnum; my $invoice_time = $self->{invoice_time}; @@ -87,14 +94,7 @@ sub taxline { push @existing_exemptions, @{ $_->cust_tax_exempt_pkg } foreach @$taxables; - my $tax_item = FS::cust_bill_pkg->new({ - 'pkgnum' => 0, - 'recur' => 0, - 'sdate' => '', - 'edate' => '', - 'itemdesc' => $name, - }); - my @tax_location; + my @tax_links; foreach my $cust_bill_pkg (@$taxables) { @@ -266,7 +266,16 @@ sub taxline { $taxable_charged = sprintf( "%.2f", $taxable_charged); next if $taxable_charged == 0; - my $this_tax_cents = int($taxable_charged * $tax_object->tax); + my $this_tax_cents = $taxable_charged * $self->tax; + if ( $round_per_line_item ) { + # Round the tax to the nearest cent for each line item, instead of + # across the whole invoice. + $this_tax_cents = sprintf('%.0f', $this_tax_cents); + } else { + # Otherwise truncate it so that rounding error is always positive. + $this_tax_cents = int($this_tax_cents); + } + my $location = FS::cust_bill_pkg_tax_location->new({ 'taxnum' => $tax_object->taxnum, 'taxtype' => ref($tax_object), @@ -274,25 +283,31 @@ sub taxline { 'pkgnum' => $cust_bill_pkg->pkgnum, 'locationnum' => $cust_bill_pkg->cust_pkg->tax_locationnum, 'taxable_cust_bill_pkg' => $cust_bill_pkg, - 'tax_cust_bill_pkg' => $tax_item, }); - push @tax_location, $location; + push @tax_links, $location; $taxable_cents += $taxable_charged; $tax_cents += $this_tax_cents; } #foreach $cust_bill_pkg - # now round and distribute + # 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); + + # if we're rounding per item, then ignore that and don't distribute any + # extra cents. + if ( $round_per_line_item ) { + $extra_cents = 0; + } + if ( $extra_cents < 0 ) { die "nonsense extra_cents value $extra_cents"; } $tax_cents += $extra_cents; my $i = 0; - foreach (@tax_location) { # can never require more than a single pass, yes? + foreach (@tax_links) { # can never require more than a single pass, yes? my $cents = $_->get('cents'); if ( $extra_cents > 0 ) { $cents++; @@ -300,10 +315,8 @@ sub taxline { } $_->set('amount', sprintf('%.2f', $cents/100)); } - $tax_item->set('setup' => sprintf('%.2f', $tax_cents / 100)); - $tax_item->set('cust_bill_pkg_tax_location', \@tax_location); - return $tax_item; + return @tax_links; } sub info {