creating address-less free customers, RT#24968
[freeside.git] / FS / FS / cust_main / Location.pm
index 5590f88..4bcffab 100644 (file)
@@ -24,11 +24,13 @@ BEGIN {
     foreach my $f (@location_fields) {
       *{"FS::cust_main::Location::$f"} = sub {
         carp "WARNING: tried to set cust_main.$f with accessor" if (@_ > 1);
-        shift->bill_location->$f
+        my $l = shift->bill_location;
+        $l ? $l->$f : '';
       };
       *{"FS::cust_main::Location::ship_$f"} = sub {
         carp "WARNING: tried to set cust_main.ship_$f with accessor" if (@_ > 1);
-        shift->ship_location->$f
+        my $l = shift->ship_location;
+        $l ? $l->$f : '';
       };
     }
     $init++;
@@ -165,7 +167,10 @@ sub _upgrade_data {
         map { $_ => $cust_main->get($_) } location_fields(),
       }
     );
-    $bill_location->set('censustract', ''); # properly goes with ship_location
+    $bill_location->set('censustract', '');
+    $bill_location->set('censusyear', '');
+     # properly goes with ship_location; if they're the same, will be set
+     # on ship_location before inserting either one
     my $ship_location = $bill_location; # until proven otherwise
 
     if ( $cust_main->get('ship_address1') ) {
@@ -187,8 +192,6 @@ sub _upgrade_data {
         );
       } # else it stays equal to $bill_location
 
-      $ship_location->set('censustract', $cust_main->get('censustract'));
-
       # Step 2: Extract shipping address contact fields into contact
       my %unlike = map { $_ => 1 }
         grep { $cust_main->get($_) ne $cust_main->get("ship_$_") }
@@ -251,6 +254,11 @@ sub _upgrade_data {
       }
     }
 
+    # this always goes with the ship_location (whether it's the same as
+    # bill_location or not)
+    $ship_location->set('censustract', $cust_main->get('censustract'));
+    $ship_location->set('censusyear',  $cust_main->get('censusyear'));
+
     $error = $bill_location->insert;
     die "error migrating billing address for customer $custnum: $error"
       if $error;
@@ -286,6 +294,38 @@ sub _upgrade_data {
     }
 
   } #foreach $cust_main
+
+  # repair an error in earlier upgrades
+  if (!FS::upgrade_journal->is_done('cust_location_censustract_repair')
+       and FS::Conf->new->exists('cust_main-require_censustract') ) {
+
+    foreach my $cust_location (
+      qsearch('cust_location', { 'censustract' => '' })
+    ) {
+      my $custnum = $cust_location->custnum;
+      next if !$custnum; # avoid doing this for prospect locations
+      my $address1 = $cust_location->address1;
+      # find the last history record that had that address
+      my $last_h = qsearchs({
+          table     => 'h_cust_main',
+          extra_sql => " WHERE custnum = $custnum AND address1 = ".
+                        dbh->quote($address1) .
+                        " AND censustract IS NOT NULL",
+          order_by  => " ORDER BY history_date DESC LIMIT 1",
+      });
+      if (!$last_h) {
+        # this is normal; just means it never had a census tract before
+        next;
+      }
+      $cust_location->set('censustract' => $last_h->get('censustract'));
+      $cust_location->set('censusyear'  => $last_h->get('censusyear'));
+      my $error = $cust_location->replace;
+      warn "Error setting census tract for customer #$custnum:\n  $error\n"
+        if $error;
+    } # foreach $cust_location
+    FS::upgrade_journal->set_done('cust_location_censustract_repair');
+  }
+
 }
 
 =back