Merge branch 'master' of git.freeside.biz:/home/git/freeside
[freeside.git] / FS / FS / cust_main.pm
index ee570da..e0855d8 100644 (file)
@@ -1325,7 +1325,7 @@ set as the contact email address for a default contact with the same name as
 the customer.
 
 Currently available options are: I<tax_exemption>, I<cust_payby_params>, 
-I<contact_params>, I<invoicing_list>.
+I<contact_params>, I<invoicing_list>, and I<move_pkgs>.
 
 The I<tax_exemption> option can be set to an arrayref of tax names or a hashref
 of tax names and exemption numbers.  FS::cust_main_exemption records will be
@@ -1339,6 +1339,9 @@ and L<FS::contact> for the fields these can contain.
 I<invoicing_list> is a synonym for the INVOICING_LIST_ARYREF parameter, and
 should be used instead if possible.
 
+If I<move_pkgs> is an arrayref, it will override the list of packages
+to be moved to the new address (see L<FS::cust_location/move_pkgs>.)
+
 =cut
 
 sub replace {
@@ -1533,7 +1536,7 @@ sub replace {
   $self->set('ship_location', ''); #flush cache
   if ( $old->ship_locationnum and # should only be null during upgrade...
        $old->ship_locationnum != $self->ship_locationnum ) {
-    $error = $old->ship_location->move_to($self->ship_location);
+    $error = $old->ship_location->move_to($self->ship_location, move_pkgs => $options{'move_pkgs'});
     if ( $error ) {
       $dbh->rollback if $oldAutoCommit;
       return $error;
@@ -5372,19 +5375,25 @@ sub queueable_upgrade {
   eval "use FS::upgrade_journal";
   die $@ if $@;
 
-  # prior to 2013 (commit f16665c9) payinfo was stored in history if not encrypted,
-  # clear that out before encrypting/tokenizing anything else
+  # prior to 2013 (commit f16665c9) payinfo was stored in history if not
+  # encrypted, clear that out before encrypting/tokenizing anything else
   if (!FS::upgrade_journal->is_done('clear_payinfo_history')) {
-    foreach my $table ('cust_payby','cust_pay_pending','cust_pay','cust_pay_void','cust_refund') {
-      my $sql = 'UPDATE h_'.$table.' SET payinfo = NULL WHERE payinfo IS NOT NULL';
+    foreach my $table (qw(
+      cust_payby cust_pay_pending cust_pay cust_pay_void cust_refund
+    )) {
+      my $sql =
+        'UPDATE h_'.$table.' SET payinfo = NULL WHERE payinfo IS NOT NULL';
       my $sth = dbh->prepare($sql) or die dbh->errstr;
       $sth->execute or die $sth->errstr;
     }
     FS::upgrade_journal->set_done('clear_payinfo_history');
   }
 
-  # encrypt old records
-  if ($conf->exists('encryption') && !FS::upgrade_journal->is_done('encryption_check')) {
+  # fix Tokenized paycardtype and encrypt old records
+  if (    ! FS::upgrade_journal->is_done('paycardtype_Tokenized')
+       || ! FS::upgrade_journal->is_done('encryption_check')
+     )
+  {
 
     # allow replacement of closed cust_pay/cust_refund records
     local $FS::payinfo_Mixin::allow_closed_replace = 1;
@@ -5396,11 +5405,15 @@ sub queueable_upgrade {
     local $FS::UID::AutoCommit = 1;
 
     # encrypt what's there
-    foreach my $table ('cust_payby','cust_pay_pending','cust_pay','cust_pay_void','cust_refund') {
+    foreach my $table (qw(
+      cust_payby cust_pay_pending cust_pay cust_pay_void cust_refund
+    )) {
       my $tclass = 'FS::'.$table;
       my $lastrecnum = 0;
       my @recnums = ();
-      while (my $recnum = _upgrade_next_recnum(dbh,$table,\$lastrecnum,\@recnums)) {
+      while (
+        my $recnum = _upgrade_next_recnum(dbh,$table,\$lastrecnum,\@recnums)
+      ) {
         my $record = $tclass->by_key($recnum);
         next unless $record; # small chance it's been deleted, that's ok
         next unless grep { $record->payby eq $_ } @FS::Record::encrypt_payby;
@@ -5410,12 +5423,20 @@ sub queueable_upgrade {
         if (!$record->custnum && $table eq 'cust_pay_pending') {
           $record->set('custnum_pending',1);
         }
+        $record->paycardtype('') if $record->paycardtype eq 'Tokenized';
+
+        local($ignore_expired_card) = 1;
+        local($ignore_banned_card) = 1;
+        local($skip_fuzzyfiles) = 1;
+        local($import) = 1;#prevent automatic geocoding (need its own variable?)
+
         my $error = $record->replace;
-        die $error if $error;
+        die "Error replacing $table ".$record->get($record->primary_key).": $error" if $error;
       }
     }
 
-    FS::upgrade_journal->set_done('encryption_check');
+    FS::upgrade_journal->set_done('paycardtype_Tokenized');
+    FS::upgrade_journal->set_done('encryption_check') if $conf->exists('encryption');
   }
 
   # now that everything's encrypted, tokenize...
@@ -5433,7 +5454,9 @@ sub _upgrade_next_recnum {
   my $sql = 'SELECT '.$tclass->primary_key.
             ' FROM '.$table.
             ' WHERE '.$tclass->primary_key.' > '.$$lastrecnum.
-            ' ORDER BY '.$tclass->primary_key.' LIMIT 500';;
+            "   AND payby IN ( 'CARD', 'DCRD', 'CHEK', 'DCHK' ) ".
+            "   AND ( length(payinfo) < 80 OR paycardtype = 'Tokenized' ) ".
+            ' ORDER BY '.$tclass->primary_key.' LIMIT 500';
   my $sth = $dbh->prepare($sql) or die $dbh->errstr;
   $sth->execute() or die $sth->errstr;
   my @recnums;