From 60dc4fe638eb9abc5a3ea92d43031dcbfeb71454 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Sat, 30 Aug 2014 18:20:52 -0700 Subject: [PATCH] enable CCH update to remove tax classes, #30670 --- FS/FS/cust_bill_pkg.pm | 3 +- FS/FS/part_pkg.pm | 5 +++- FS/FS/part_pkg_taxrate.pm | 28 +++++++++++-------- FS/FS/tax_class.pm | 70 +++++++++++++++++++---------------------------- FS/FS/tax_rate.pm | 24 ++++++++-------- 5 files changed, 63 insertions(+), 67 deletions(-) diff --git a/FS/FS/cust_bill_pkg.pm b/FS/FS/cust_bill_pkg.pm index 689d6c607..78b8b0fb3 100644 --- a/FS/FS/cust_bill_pkg.pm +++ b/FS/FS/cust_bill_pkg.pm @@ -1242,7 +1242,8 @@ sub upgrade_tax_location { next INVOICE; } } - my $exempt_cust = 1 if $h_cust_main->tax; + my $exempt_cust; + $exempt_cust = 1 if $h_cust_main->tax; # classify line items my @tax_items; diff --git a/FS/FS/part_pkg.pm b/FS/FS/part_pkg.pm index 042cb5c56..77f70e4a3 100644 --- a/FS/FS/part_pkg.pm +++ b/FS/FS/part_pkg.pm @@ -1561,8 +1561,10 @@ package in the location specified by GEOCODE, for usage class CLASS (one of sub tax_rates { my $self = shift; my ($vendor, $geocode, $class) = @_; + # if this part_pkg is overridden into a specific taxclass, get that class my @taxclassnums = map { $_->taxclassnum } $self->part_pkg_taxoverride($class); + # otherwise, get its tax product category if (!@taxclassnums) { my $part_pkg_taxproduct = $self->taxproduct($class); # If this isn't defined, then the class has no taxproduct designation, @@ -1583,7 +1585,8 @@ sub tax_rates { my $extra_sql = "AND taxclassnum IN (". join(',', @taxclassnums) . ")"; my @taxes = qsearch({ 'table' => 'tax_rate', 'hashref' => { 'geocode' => $geocode, - 'data_vendor' => $vendor }, + 'data_vendor' => $vendor, + 'disabled' => '' }, 'extra_sql' => $extra_sql, }); warn "Found taxes ". join(',', map {$_->taxnum} @taxes) ."\n" diff --git a/FS/FS/part_pkg_taxrate.pm b/FS/FS/part_pkg_taxrate.pm index a73272040..bfb1ea8e2 100644 --- a/FS/FS/part_pkg_taxrate.pm +++ b/FS/FS/part_pkg_taxrate.pm @@ -243,9 +243,12 @@ sub batch_import { ); unless ($part_pkg_taxproduct) { - return "Can't find part_pkg_taxproduct for txmatrix deletion: ". - join(" ", map { "$_ => ". $hash->{$_} } @fields) - if ($hash->{'actionfield'} && $hash->{'actionflag'} eq 'D'); + if (($hash->{'actionfield'} || '') eq 'D') { + warn "WARNING: Can't find part_pkg_taxproduct for txmatrix deletion: ". + join(" ", map { "$_ => ". $hash->{$_} } @fields) . + " (ignored)\n"; + next; + } $part_pkg_taxproduct{'description'} = join(' : ', (map{ $hash->{$_} } qw(groupdesc itemdesc)), @@ -262,6 +265,8 @@ sub batch_import { delete($hash->{$_}) for qw(group groupdesc item itemdesc provider customer rectype ); + + # resolve the taxtype/taxcat fields to taxclassnums my %map = ( 'taxclassnum' => [ 'taxtype', 'taxcat' ], 'taxclassnumtaxed' => [ 'taxtypetaxed', 'taxcattaxed' ], @@ -275,14 +280,13 @@ sub batch_import { 'taxclass' => $class, } ); - $hash->{$item} = $tax_class->taxclassnum - if $tax_class; - - return "Can't find tax class for txmatrix deletion: ". - join(" ", map { "$_ => ". $hash->{$_} } @fields) - if ( $hash->{'actionflag'} && $hash->{'actionflag'} eq 'D' && - !$tax_class && $class ne ':' - ); + if ( $tax_class ) { + $hash->{$item} = $tax_class->taxclassnum; + } elsif ($class ne ':' and ($hash->{actionflag} || '') eq 'D') { + # return "Can't find tax class for txmatrix deletion: ". + warn "WARNING: Can't find tax class $class for txmatrix deletion (ignored)\n"; + return ''; # don't delete the record, then + } delete($hash->{$_}) foreach @{$map{$item}}; } @@ -319,7 +323,7 @@ sub batch_import { $hash->{taxproductnum} .= ' ( '. $taxproduct->taxproduct. ' )' if $taxproduct; } - return "Can't find part_pkg_taxrate to delete: ". + warn "WARNING: Can't find part_pkg_taxrate to delete: ". join(" ", map { "$_ => *". $hash->{$_}. '*' } keys(%$hash) ); } diff --git a/FS/FS/tax_class.pm b/FS/FS/tax_class.pm index d68e7e30c..04e9d37f9 100644 --- a/FS/FS/tax_class.pm +++ b/FS/FS/tax_class.pm @@ -85,52 +85,38 @@ Delete this record from the database. sub delete { my $self = shift; - return "Can't delete a tax class which has package tax rates!" - if qsearch( 'part_pkg_taxrate', { 'taxclassnumtaxed' => $self->taxclassnum } ); - - return "Can't delete a tax class which has package tax overrides!" - if qsearch( 'part_pkg_taxoverride', { 'taxclassnum' => $self->taxclassnum } ); - - local $SIG{HUP} = 'IGNORE'; - local $SIG{INT} = 'IGNORE'; - local $SIG{QUIT} = 'IGNORE'; - local $SIG{TERM} = 'IGNORE'; - local $SIG{TSTP} = 'IGNORE'; - local $SIG{PIPE} = 'IGNORE'; - - my $oldAutoCommit = $FS::UID::AutoCommit; - local $FS::UID::AutoCommit = 0; - my $dbh = dbh; - - foreach my $tax_rate ( - qsearch( 'tax_rate', { taxclassnum=>$self->taxclassnum } ) - ) { - my $error = $tax_rate->delete; - if ( $error ) { - $dbh->rollback if $oldAutoCommit; - return $error; - } + #return "Can't delete a tax class which has package tax rates!" + #if qsearch( 'part_pkg_taxrate', { 'taxclassnumtaxed' => $self->taxclassnum + # If this tax class is manually assigned to a package, + # then return a useful error message instead of just having a conniption. + my @overrides = qsearch( 'part_pkg_taxoverride', { + 'taxclassnum' => $self->taxclassnum + } ); + if (@overrides) { + return "Tried to delete tax class " . $self->taxclass . + ", which is assigned to package definition " . + join(', ', map { '#'.$_->pkgpart} @overrides) . + "."; } - foreach my $part_pkg_taxrate ( - qsearch( 'part_pkg_taxrate', { taxclassnum=>$self->taxclassnum } ) - ) { - my $error = $part_pkg_taxrate->delete; - if ( $error ) { - $dbh->rollback if $oldAutoCommit; - return $error; - } + # part_pkg_taxrate.taxclass identifies taxes belonging to this taxclass. + # part_pkg_taxrate.taxclassnumtaxed identifies taxes applying to this + # taxclass. + # If this taxclass goes away, remove all of them. (CCH upgrade CAN'T + # remove them, because it removes the tax_class first and then doesn't + # know what the taxclassnum was. Yeah, I know. So it will just skip + # over them at the TXMATRIX stage.) + my @part_pkg_taxrate = ( + qsearch('part_pkg_taxrate', { 'taxclassnum' => $self->taxclassnum }), + qsearch('part_pkg_taxrate', { 'taxclassnumtaxed' => $self->taxclassnum }) + ); + foreach (@part_pkg_taxrate) { + my $error = $_->delete; + return "when deleting taxclass ".$self->taxclass.": $error" + if $error; } - my $error = $self->SUPER::delete(@_); - if ( $error ) { - $dbh->rollback if $oldAutoCommit; - return $error; - } - - $dbh->commit or die $dbh->errstr if $oldAutoCommit; - - ''; + $self->SUPER::delete(@_); } diff --git a/FS/FS/tax_rate.pm b/FS/FS/tax_rate.pm index 9e458e27f..6bc5e18e9 100644 --- a/FS/FS/tax_rate.pm +++ b/FS/FS/tax_rate.pm @@ -880,20 +880,22 @@ sub batch_import { } my $tax_rate = qsearchs( 'tax_rate', $delete{$_} ); - unless ($tax_rate) { + if (!$tax_rate) { $dbh->rollback if $oldAutoCommit; $tax_rate = $delete{$_}; - return "can't find tax_rate to delete for: ". - #join(" ", map { "$_ => ". $tax_rate->{$_} } @fields); - join(" ", map { "$_ => ". $tax_rate->{$_} } keys(%$tax_rate) ); - } - my $error = $tax_rate->delete; + warn "WARNING: can't find tax_rate to delete for: ". + join(" ", map { "$_ => ". $tax_rate->{$_} } keys(%$tax_rate) ). + " (ignoring)\n"; + } else { + my $error = $tax_rate->delete; # XXX we really should not do this + # (it orphans CBPTRL records) - if ( $error ) { - $dbh->rollback if $oldAutoCommit; - my $hashref = $delete{$_}; - $line = join(", ", map { "$_ => ". $hashref->{$_} } keys(%$hashref) ); - return "can't delete tax_rate for $line: $error"; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + my $hashref = $delete{$_}; + $line = join(", ", map { "$_ => ". $hashref->{$_} } keys(%$hashref) ); + return "can't delete tax_rate for $line: $error"; + } } $imported++; -- 2.11.0