+ } else { #do it now
+ process_upgrade_location();
+ }
+
+ }
+
+ # 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');
+ }
+}
+
+sub process_upgrade_location {
+ my $class = shift;
+
+ my $dbh = dbh;
+ local $FS::cust_main::import = 1;
+ local $FS::cust_location::import = 1;
+ local $FS::contact::skip_fuzzyfiles = 1;
+ local $FS::UID::AutoCommit = 0;
+
+ my $tax_prefix = 'bill_';
+ if ( FS::Conf->new->exists('tax-ship_address') ) {
+ $tax_prefix = 'ship_';
+ }
+
+ # load some records that were created during the initial upgrade
+ my $service_contact_class =
+ qsearchs('contact_class', { classname => 'Service'});
+
+ my %phone_type = (
+ daytime => 'Work',
+ night => 'Home',
+ mobile => 'Mobile',
+ fax => 'Fax'
+ );
+ foreach (keys %phone_type) {
+ $phone_type{$_} = qsearchs('phone_type', { typename => $phone_type{$_}});
+ }
+
+ my %opt = (
+ tax_prefix => $tax_prefix,
+ service_contact_class => $service_contact_class,
+ phone_type => \%phone_type,
+ );
+
+ my $search = FS::Cursor->new('cust_main',
+ { bill_locationnum => '',
+ address1 => { op=>'!=', value=>'' }
+ });
+ while (my $cust_main = $search->fetch) {
+ my $error = $cust_main->upgrade_location(%opt);
+ if ( $error ) {
+ warn "cust#".$cust_main->custnum.": $error\n";
+ $dbh->rollback;
+ } else {
+ # commit as we go
+ $dbh->commit;
+ }
+ }
+}
+
+sub upgrade_location { # instance method
+ my $cust_main = shift;
+ my %opt = @_;
+ my $error;