fix cch update removal of PLUS4/ZIP and TXMATRIX, RT#21687
[freeside.git] / FS / FS / tax_rate.pm
index 48c0196..2653833 100644 (file)
@@ -10,6 +10,7 @@ use DateTime::Format::Strptime;
 use Storable qw( thaw nfreeze );
 use IO::File;
 use File::Temp;
+use Text::CSV_XS;
 use LWP::UserAgent;
 use HTTP::Request;
 use HTTP::Response;
@@ -637,6 +638,7 @@ sub batch_import {
   $count *=2;
 
   if ( $format eq 'cch' || $format eq 'cch-update' ) {
+    #false laziness w/below (sub _perform_cch_diff)
     @fields = qw( geocode inoutcity inoutlocal tax location taxbase taxmax
                   excessrate effective_date taxauth taxtype taxcat taxname
                   usetax useexcessrate fee unittype feemax maxtype passflag
@@ -715,9 +717,6 @@ sub batch_import {
     die "unknown format $format";
   }
 
-  eval "use Text::CSV_XS;";
-  die $@ if $@;
-
   my $csv = new Text::CSV_XS;
 
   my $imported = 0;
@@ -758,9 +757,10 @@ sub batch_import {
     foreach my $field ( @fields ) {
       $tax_rate{$field} = shift @columns; 
     }
+
     if ( scalar( @columns ) ) {
       $dbh->rollback if $oldAutoCommit;
-      return "Unexpected trailing columns in line (wrong format?): $line";
+      return "Unexpected trailing columns in line (wrong format?) importing tax_rate: $line";
     }
 
     my $error = &{$hook}(\%tax_rate);
@@ -785,7 +785,8 @@ sub batch_import {
 
   }
 
-  for (grep { !exists($delete{$_}) } keys %insert) {
+  my @replace = grep { exists($delete{$_}) } keys %insert;
+  for (@replace) {
     if ( $job ) {  # progress bar
       if ( time - $min_sec > $last ) {
         my $error = $job->update_statustext(
@@ -799,20 +800,35 @@ sub batch_import {
       }
     }
 
-    my $tax_rate = new FS::tax_rate( $insert{$_} );
-    my $error = $tax_rate->insert;
+    my $old = qsearchs( 'tax_rate', $delete{$_} );
 
-    if ( $error ) {
-      $dbh->rollback if $oldAutoCommit;
-      my $hashref = $insert{$_};
-      $line = join(", ", map { "$_ => ". $hashref->{$_} } keys(%$hashref) );
-      return "can't insert tax_rate for $line: $error";
+    if ( $old ) {
+
+      my $new = new FS::tax_rate({ $old->hash, %{$insert{$_}}, 'manual' => ''  });
+      $new->taxnum($old->taxnum);
+      my $error = $new->replace($old);
+
+      if ( $error ) {
+        $dbh->rollback if $oldAutoCommit;
+        my $hashref = $insert{$_};
+        $line = join(", ", map { "$_ => ". $hashref->{$_} } keys(%$hashref) );
+        return "can't replace tax_rate for $line: $error";
+      }
+
+      $imported++;
+
+    } else {
+
+      $old = delete $delete{$_};
+      warn "WARNING: can't find tax_rate to replace (inserting instead and continuing) for: ".
+        #join(" ", map { "$_ => ". $old->{$_} } @fields);
+        join(" ", map { "$_ => ". $old->{$_} } keys(%$old) );
     }
 
     $imported++;
   }
 
-  for (grep { exists($delete{$_}) } keys %insert) {
+  for (grep { !exists($delete{$_}) } keys %insert) {
     if ( $job ) {  # progress bar
       if ( time - $min_sec > $last ) {
         my $error = $job->update_statustext(
@@ -826,27 +842,17 @@ sub batch_import {
       }
     }
 
-    my $old = qsearchs( 'tax_rate', $delete{$_} );
-    unless ($old) {
-      $dbh->rollback if $oldAutoCommit;
-      $old = $delete{$_};
-      return "can't find tax_rate to replace for: ".
-        #join(" ", map { "$_ => ". $old->{$_} } @fields);
-        join(" ", map { "$_ => ". $old->{$_} } keys(%$old) );
-    }
-    my $new = new FS::tax_rate({ $old->hash, %{$insert{$_}}, 'manual' => ''  });
-    $new->taxnum($old->taxnum);
-    my $error = $new->replace($old);
+    my $tax_rate = new FS::tax_rate( $insert{$_} );
+    my $error = $tax_rate->insert;
 
     if ( $error ) {
       $dbh->rollback if $oldAutoCommit;
       my $hashref = $insert{$_};
       $line = join(", ", map { "$_ => ". $hashref->{$_} } keys(%$hashref) );
-      return "can't replace tax_rate for $line: $error";
+      return "can't insert tax_rate for $line: $error";
     }
 
     $imported++;
-    $imported++;
   }
 
   for (grep { !exists($insert{$_}) } keys %delete) {
@@ -961,7 +967,7 @@ sub _perform_batch_import {
       my $file = lc($name). 'file';
 
       unless ($files{$file}) {
-        $error = "No $name supplied";
+        #$error = "No $name supplied";
         next;
       }
       next if $name eq 'DETAIL' && $format =~ /update/;
@@ -978,7 +984,7 @@ sub _perform_batch_import {
         unlink $filename or warn "Can't delete $filename: $!"
           unless $keep_cch_files;
         push @insert_list, $name, $insertname, $import_sub, $format;
-        if ( $name eq 'GEOCODE' ) { #handle this whole ordering issue better
+        if ( $name eq 'GEOCODE' || $name eq 'CODE' ) { #handle this whole ordering issue better
           unshift @predelete_list, $name, $deletename, $import_sub, $format;
         } else {
           unshift @delete_list, $name, $deletename, $import_sub, $format;
@@ -993,13 +999,20 @@ sub _perform_batch_import {
     }
 
     push @insert_list,
-      'DETAIL', "$dir/".$files{detail}, \&FS::tax_rate::batch_import, $format
+      'DETAIL', "$dir/".$files{detailfile}, \&FS::tax_rate::batch_import, $format
       if $format =~ /update/;
 
+    my %addl_param = ();
+    if ( $param->{'delete_only'} ) {
+      $addl_param{'delete_only'} = $param->{'delete_only'};
+      @insert_list = () 
+    }
+
     $error ||= _perform_cch_tax_import( $job,
                                         [ @predelete_list ],
                                         [ @insert_list ],
                                         [ @delete_list ],
+                                        \%addl_param,
     );
     
     
@@ -1024,7 +1037,8 @@ sub _perform_batch_import {
 
 
 sub _perform_cch_tax_import {
-  my ( $job, $predelete_list, $insert_list, $delete_list ) = @_;
+  my ( $job, $predelete_list, $insert_list, $delete_list, $addl_param ) = @_;
+  $addl_param ||= {};
 
   my $error = '';
   foreach my $list ($predelete_list, $insert_list, $delete_list) {
@@ -1033,7 +1047,11 @@ sub _perform_cch_tax_import {
       my $fmt = "$format-update";
       $fmt = $format. ( lc($name) eq 'zip' ? '-zip' : '' );
       open my $fh, "< $file" or $error ||= "Can't open $name file $file: $!";
-      $error ||= &{$method}({ 'filehandle' => $fh, 'format' => $fmt }, $job);
+      my $param = { 'filehandle' => $fh,
+                    'format'     => $fmt,
+                    %$addl_param,
+                  };
+      $error ||= &{$method}($param, $job);
       close $fh;
     }
   }
@@ -1115,8 +1133,26 @@ sub _perform_cch_diff {
   }
   close $newcsvfh;
 
-  for (keys %oldlines) {
-    print $dfh $_, ',"D"', "\n" if $oldlines{$_};
+  #false laziness w/above (sub batch_import)
+  my @fields = qw( geocode inoutcity inoutlocal tax location taxbase taxmax
+                   excessrate effective_date taxauth taxtype taxcat taxname
+                   usetax useexcessrate fee unittype feemax maxtype passflag
+                   passtype basetype );
+  my $numfields = scalar(@fields);
+
+  my $csv = new Text::CSV_XS { 'always_quote' => 1 };
+
+  for my $line (grep $oldlines{$_}, keys %oldlines) {
+
+    $csv->parse($line) or do {
+      #$dbh->rollback if $oldAutoCommit;
+      die "can't parse: ". $csv->error_input();
+    };
+    my @columns = $csv->fields();
+    
+    $csv->combine( splice(@columns, 0, $numfields) );
+
+    print $dfh $csv->string, ',"D"', "\n";
   }
 
   close $dfh;
@@ -1170,9 +1206,6 @@ sub _cch_fetch_and_unzip {
 sub _cch_extract_csv_from_dbf {
   my ( $job, $dir, $name ) = @_;
 
-  eval "use Text::CSV_XS;";
-  die $@ if $@;
-
   eval "use XBase;";
   die $@ if $@;
 
@@ -1635,16 +1668,16 @@ sub process_download_and_update {
 
     if (-d $dir) {
 
-      if (-d "$dir.4") {
-        opendir(my $dirh, "$dir.4") or die "failed to open $dir.4: $!\n";
+      if (-d "$dir.9") {
+        opendir(my $dirh, "$dir.9") or die "failed to open $dir.9: $!\n";
         foreach my $file (readdir($dirh)) {
-          unlink "$dir.4/$file" if (-f "$dir.4/$file");
+          unlink "$dir.9/$file" if (-f "$dir.9/$file");
         }
         closedir($dirh);
-        rmdir "$dir.4";
+        rmdir "$dir.9";
       }
 
-      for (3, 2, 1) {
+      for (8, 7, 6, 5, 4, 3, 2, 1) {
         if ( -e "$dir.$_" ) {
           rename "$dir.$_", "$dir.". ($_+1) or die "can't rename $dir.$_: $!\n";
         }