use FS::UID qw(dbh);
use FS::Record qw( qsearch qsearchs );
use FS::Misc qw( csv_from_fixed );
+use FS::part_pkg_taxrate;
+use FS::part_pkg_taxoverride;
@ISA = qw(FS::Record);
sub delete {
my $self = shift;
- return "Can't delete a tax class which has tax rates!"
- if qsearch( 'tax_rate', { 'taxclassnum' => $self->taxclassnum } );
-
- return "Can't delete a tax class which has package tax rates!"
- if qsearch( 'part_pkg_taxrate', { 'taxclassnum' => $self->taxclassnum } );
-
- 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 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) .
+ ".";
+ }
- return "Can't delete a tax class which has package tax overrides!"
- if qsearch( 'part_pkg_taxoverride', { 'taxclassnum' => $self->taxclassnum } );
+ # 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;
+ }
$self->SUPER::delete(@_);
-
+
}
=item replace OLD_RECORD
}
}
- my $tax_class =
- new FS::tax_class( { 'data_vendor' => 'cch',
- 'taxclass' => $type->[0].':'.$cat->[0],
- 'description' => $type->[1].':'.$cat->[1],
- } );
- my $error = $tax_class->insert;
- return "can't insert tax_class for old TAXTYPE $type and new TAXCAT $cat: $error" if $error;
+ my %hash = ( 'data_vendor' => 'cch',
+ 'taxclass' => $type->[0].':'.$cat->[0],
+ 'description' => $type->[1].':'.$cat->[1],
+ );
+ unless ( qsearchs('tax_class', \%hash) ) {
+ my $tax_class = new FS::tax_class \%hash;
+ my $error = $tax_class->insert;
+
+ return "can't insert tax_class for ".
+ " old TAXTYPE ". $type->[0].':'.$type->[1].
+ " and new TAXCAT ". $cat->[0].':'. $cat->[1].
+ " : $error"
+ if $error;
+ }
+
$imported++;
+
}
}
- my %cats = map { $_=>1 } ( @old_cats, @{$data->{'taxcat'}} );
-
foreach my $type (@{$data->{'taxtype'}}) {
- foreach my $cat (keys %cats) {
+ foreach my $cat (@old_cats, @{$data->{'taxcat'}}) {
if ( $job ) { # progress bar
if ( time - $min_sec > $last ) {
=head1 BUGS
- batch_import does not handle mixed I and D records in the same file for
- format cch-update
-
=head1 SEE ALSO
L<FS::Record>, schema.html from the base documentation.