add skip_dcontext_suffix to skip CDRs with dcontext ending in a definable string...
[freeside.git] / FS / FS / part_pkg_taxclass.pm
index 341be0e..055c778 100644 (file)
@@ -2,7 +2,10 @@ package FS::part_pkg_taxclass;
 
 use strict;
 use vars qw( @ISA );
-use FS::Record qw( qsearch qsearchs );
+use Scalar::Util qw( blessed );
+use FS::UID qw( dbh );
+use FS::Record; # qw( qsearch qsearchs );
+use FS::cust_main_county;
 
 @ISA = qw(FS::Record);
 
@@ -27,8 +30,16 @@ FS::part_pkg_taxclass - Object methods for part_pkg_taxclass records
 
 =head1 DESCRIPTION
 
-An FS::part_pkg_taxclass object represents a tax class.  FS::part_pkg_taxclass
-inherits from FS::Record.  The following fields are currently supported:
+An FS::part_pkg_taxclass object declares the existence of a taxable sales
+class.  FS::part_pkg_taxclass inherits from FS::Record.  
+
+FS::part_pkg_taxclass is not used in tax calculation.  It is only used to 
+list a set of valid tax class names for use in the user interface.  When
+using internal taxes, the actual matching of tax definitions to package
+tax class is a string match between tax class names.  This is arguably
+a bug.
+
+The following fields are currently supported:
 
 =over 4
 
@@ -40,6 +51,10 @@ Primary key
 
 Tax class
 
+=item disabled
+
+Disabled flag, empty or 'Y'
+
 =back
 
 =head1 METHODS
@@ -66,7 +81,57 @@ otherwise returns false.
 
 =cut
 
-# the insert method can be inherited from FS::Record
+sub insert {
+  my $self = shift;
+
+  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;
+
+  my $error = $self->SUPER::insert;
+  if ( $error ) {
+    $dbh->rollback if $oldAutoCommit;
+    return $error;
+  }
+
+  my $sth = dbh->prepare("
+    SELECT country, state, county FROM cust_main_county
+      WHERE taxclass IS NOT NULL AND taxclass != ''
+      GROUP BY country, state, county
+  ") or die dbh->errstr;
+  $sth->execute or die $sth->errstr;
+
+  while ( my $row = $sth->fetchrow_hashref ) {
+    #warn "inserting for $row";
+    my $cust_main_county = new FS::cust_main_county {
+      'country'  => $row->{country},
+      'state'    => $row->{state},
+      'county'   => $row->{county},
+      'tax'      => 0,
+      'taxclass' => $self->taxclass,
+      #exempt_amount
+      #taxname
+      #setuptax
+      #recurtax
+    };
+    $error = $cust_main_county->insert;
+    #last if $error;
+    if ( $error ) {
+      $dbh->rollback if $oldAutoCommit;
+      return $error;
+    }
+  }
+
+  $dbh->commit or die $dbh->errstr if $oldAutoCommit;
+  '';
+}
 
 =item delete
 
@@ -83,7 +148,18 @@ returns the error, otherwise returns false.
 
 =cut
 
-# the replace method can be inherited from FS::Record
+sub replace {
+  my $new = shift;
+
+  my $old = ( blessed($_[0]) && $_[0]->isa('FS::Record') )
+              ? shift
+              : $new->replace_old;
+
+  return "Can't change tax class name (disable and create anew)"
+    if $old->taxclass ne $new->taxclass;
+
+  $new->SUPER::replace(@_);
+}
 
 =item check
 
@@ -100,9 +176,9 @@ sub check {
   my $self = shift;
 
   my $error = 
-    $self->ut_numbern('serial')
-    || $self->ut_number('taxclassnum')
+    $self->ut_numbern('taxclassnum')
     || $self->ut_text('taxclass')
+    || $self->ut_enum('disabled', [ '', 'Y' ] )
   ;
   return $error if $error;
 
@@ -111,6 +187,38 @@ sub check {
 
 =back
 
+=cut
+
+# _upgrade_data
+#
+# Used by FS::Upgrade to migrate to a new database.
+
+sub _upgrade_data { # class method
+  my ($class, %opts) = @_;
+
+  my $sth = dbh->prepare('
+    SELECT DISTINCT taxclass
+      FROM cust_main_county
+        LEFT JOIN part_pkg_taxclass USING ( taxclass )
+      WHERE taxclassnum IS NULL
+        AND taxclass IS NOT NULL
+  ') or die dbh->errstr;
+  $sth->execute or die $sth->errstr;
+  my %taxclass = map { $_->[0] => 1 } @{$sth->fetchall_arrayref};
+  my @taxclass = grep $_, keys %taxclass;
+
+  foreach my $taxclass ( @taxclass ) {
+
+    my $part_pkg_taxclass = new FS::part_pkg_taxclass ( {
+      'taxclass' => $taxclass,
+    } );
+    my $error = $part_pkg_taxclass->insert;
+    die $error if $error;
+
+  }
+
+}
+
 =head1 BUGS
 
 Other tables (cust_main_county, part_pkg, agent_payment_gateway) have a text