add customer fields option with agent, display_custnum, status and name, RT#73721
[freeside.git] / FS / FS / cust_main_county.pm
index 65fb722..5325fa5 100644 (file)
@@ -717,7 +717,7 @@ sub _upgrade_data {
   my $class = shift;
   # assume taxes in Washington with district numbers, and null name, or 
   # named 'sales tax', are looked up via the wa_sales method. mark them.
-  my $journal = 'cust_main_county__source_wa_sales';
+  my $journal = 'cust_main_county__source_wa_sales_201611';
   if (!FS::upgrade_journal->is_done($journal)) {
     my @taxes = qsearch({
         'table'     => 'cust_main_county',
@@ -737,26 +737,6 @@ sub _upgrade_data {
   }
   my @key_fields = (qw(city county state country district taxname taxclass));
 
-  # remove duplicates (except disabled records)
-  my @duplicate_sets = qsearch({
-    table => 'cust_main_county',
-    select => FS::Record::group_concat_sql('taxnum', ',') . ' AS taxnums, ' .
-              join(',', @key_fields),
-    extra_sql => ' WHERE tax > 0
-      GROUP BY city, county, state, country, district, taxname, taxclass
-      HAVING COUNT(*) > 1'
-  });
-  warn "Found ".scalar(@duplicate_sets)." set(s) of duplicate tax definitions\n"
-    if @duplicate_sets;
-  foreach my $set (@duplicate_sets) {
-    my @taxnums = split(',', $set->get('taxnums'));
-    my $first = FS::cust_main_county->by_key(shift @taxnums);
-    foreach my $taxnum (@taxnums) {
-      my $record = FS::cust_main_county->by_key($taxnum);
-      $record->_merge_into($first);
-    }
-  }
-
   # trim whitespace and convert to uppercase in the 'city' field.
   foreach my $record (qsearch({
     table => 'cust_main_county',
@@ -777,6 +757,107 @@ sub _upgrade_data {
       die $error if $error;
     }
   } # foreach $record
+
+  # separate wa_sales taxes by tax class as needed
+  my $district_taxname = $conf->config('tax_district_taxname');
+  $journal = 'cust_main_county__district_taxclass';
+  if (!FS::upgrade_journal->is_done($journal)
+      and $conf->exists('enable_taxclasses')) {
+    eval "use FS::part_pkg_taxclass";
+    my @taxes = qsearch({
+        'table'     => 'cust_main_county',
+        'extra_sql' => " WHERE tax > 0 AND country = 'US' AND state = 'WA'".
+                       " AND district IS NOT NULL AND  source = 'wa_sales'".
+                       " AND taxclass IS NULL"
+    });
+    my @classes = FS::part_pkg_taxclass->taxclass_names;
+    if ( @taxes ) {
+      warn "Separating WA sales taxes: ".scalar(@taxes)." records.\n";
+      foreach my $oldtax (@taxes) {
+        my $error;
+        my $taxnum = $oldtax->taxnum;
+        warn "Separating tax #$taxnum into classes\n";
+        foreach my $taxclass (@classes) {
+          # ensure that we end up with a single copy of the tax in this
+          # jurisdiction+class. there may already be one (or more) there.
+          # if so, they all represent the same tax; merge them together.
+          my %newtax_hash = (
+            'country'   => 'US',
+            'state'     => 'WA',
+            'city'      => $oldtax->city,
+            'district'  => $oldtax->district,
+            'taxclass'  => $taxclass,
+            'source'    => 'wa_sales',
+          );
+          my @taxes_in_class = qsearch('cust_main_county', {
+            %newtax_hash,
+            'tax'       => { op => '>', value => 0 },
+            'setuptax'  => '',
+            'recurtax'  => '',
+          });
+          my $newtax = shift @taxes_in_class;
+          if ($newtax) {
+            foreach (@taxes_in_class) {
+              # allow the merge, even if this somehow differs.
+              $_->set('tax', $newtax->tax);
+              $_->_merge_into($newtax);
+            }
+          }
+          $newtax ||= FS::cust_main_county->new(\%newtax_hash);
+          # copy properties from the pre-split tax
+          $newtax->set('tax', $oldtax->tax);
+          $newtax->set('setuptax', $oldtax->setuptax);
+          $newtax->set('recurtax', $oldtax->recurtax);
+          # and assign the defined tax name
+          $newtax->set('taxname', $district_taxname);
+          $error = ($newtax->taxnum ? $newtax->replace : $newtax->insert);
+          die "splitting taxnum ".$oldtax->taxnum.": $error\n" if $error;
+        } # foreach $taxclass
+        $oldtax->set('tax', 0);
+        $error = $oldtax->replace;
+        die "splitting taxnum ".$oldtax->taxnum.": $error\n" if $error;
+      }
+    }
+    FS::upgrade_journal->set_done($journal);
+  }
+
+  # also ensure they all have the chosen taxname now
+  if ($district_taxname) {
+    my @taxes = qsearch('cust_main_county', {
+      'source'  => 'wa_sales',
+      'taxname' => { op => '!=', value => $district_taxname }
+    });
+    if (@taxes) {
+      warn "Renaming WA sales taxes: ".scalar(@taxes)." records.\n";
+      foreach my $tax (@taxes) {
+        $tax->set('taxname', $district_taxname);
+        my $error = $tax->replace;
+        die "renaming taxnum ".$tax->taxnum.": $error\n" if $error;
+      }   
+    }
+  }
+
+  # remove duplicates (except disabled records)
+  my @duplicate_sets = qsearch({
+    table => 'cust_main_county',
+    select => FS::Record::group_concat_sql('taxnum', ',') . ' AS taxnums, ' .
+              join(',', @key_fields),
+    extra_sql => ' WHERE tax > 0
+      GROUP BY city, county, state, country, district, taxname, taxclass
+      HAVING COUNT(*) > 1'
+  });
+  warn "Found ".scalar(@duplicate_sets)." set(s) of duplicate tax definitions\n"
+    if @duplicate_sets;
+  foreach my $set (@duplicate_sets) {
+    my @taxnums = split(',', $set->get('taxnums'));
+    my $first = FS::cust_main_county->by_key(shift @taxnums);
+    foreach my $taxnum (@taxnums) {
+      my $record = FS::cust_main_county->by_key($taxnum);
+      $record->_merge_into($first);
+    }
+  }
+
   '';
 }