Merge branch 'FREESIDE_3_BRANCH' of git.freeside.biz:/home/git/freeside into FREESIDE...
[freeside.git] / FS / FS / cust_main.pm
index 551f8b3..621f3d1 100644 (file)
@@ -1968,8 +1968,19 @@ sub check {
     validate($payinfo)
       or return gettext('invalid_card'); # . ": ". $self->payinfo;
 
-    my $cardtype = cardtype($payinfo);
-    $cardtype = 'Tokenized' if $self->payinfo =~ /^99\d{14}$/; # token
+    my $cardtype = $self->paycardtype;
+    if ( $payinfo =~ /^99\d{14}$/ ) {
+      $self->set('is_tokenized', 'Y'); #so we don't try to do it again
+      if ( $self->paymask =~ /^\d+x/ ) {
+        $cardtype = cardtype($self->paymask);
+      } else {
+        #return "paycardtype required ".
+        #       "(can't derive from a token and no paymask w/prefix provided)"
+        #  unless $cardtype;
+      }
+    } else {
+      $cardtype = cardtype($self->payinfo);
+    }
 
     return gettext('unknown_card_type') if $cardtype eq 'Unknown';
 
@@ -2186,7 +2197,6 @@ sub check_payinfo_cardtype {
   $payinfo =~ s/\D//g;
 
   if ( $payinfo =~ /^99\d{14}$/ ) {
-    $self->set('paycardtype', 'Tokenized');
     return '';
   }
 
@@ -2780,7 +2790,7 @@ sub batch_card {
   } );
 
   foreach (qw( address1 address2 city state zip country latitude longitude
-               payby payinfo paydate payname ))
+               payby payinfo paydate payname paycode paytype ))
   {
     $options{$_} = '' unless exists($options{$_});
   }
@@ -2804,9 +2814,15 @@ sub batch_card {
     'country'  => $options{country}  || $loc->country,
     'payby'    => $options{payby}    || $self->payby,
     'payinfo'  => $options{payinfo}  || $self->payinfo,
+    'paymask'  => ( $options{payinfo}
+                      ? FS::payinfo_Mixin->mask_payinfo( $options{payby},
+                                                         $options{payinfo} )
+                      : $self->paymask
+                  ),
     'exp'      => $options{paydate}  || $self->paydate,
     'payname'  => $options{payname}  || $self->payname,
     'amount'   => $amount,                         # consolidating
+    'paycode'  => $options{paycode}  || '',
   } );
   
   $cust_pay_batch->paybatchnum($old_cust_pay_batch->paybatchnum)
@@ -5169,121 +5185,6 @@ sub search {
 
 =over 4
 
-=item batch_charge
-
-=cut
-
-sub batch_charge {
-  my $param = shift;
-  #warn join('-',keys %$param);
-  my $fh = $param->{filehandle};
-  my $agentnum = $param->{agentnum};
-  my $format = $param->{format};
-
-  my $extra_sql = ' AND '. $FS::CurrentUser::CurrentUser->agentnums_sql;
-
-  my @fields;
-  if ( $format eq 'simple' ) {
-    @fields = qw( custnum agent_custid amount pkg );
-  } else {
-    die "unknown format $format";
-  }
-
-  eval "use Text::CSV_XS;";
-  die $@ if $@;
-
-  my $csv = new Text::CSV_XS;
-  #warn $csv;
-  #warn $fh;
-
-  my $imported = 0;
-  #my $columns;
-
-  local $SIG{HUP} = 'IGNORE';
-  local $SIG{INT} = 'IGNORE';
-  local $SIG{QUIT} = 'IGNORE';
-  local $SIG{TERM} = 'IGNORE';
-  local $SIG{TSTP} = 'IGNORE';
-  local $SIG{PIPE} = 'IGNORE';
-
-  my $oldAutoCommit = $FS::UID::AutoCommit;
-  local $FS::UID::AutoCommit = 0;
-  my $dbh = dbh;
-  
-  #while ( $columns = $csv->getline($fh) ) {
-  my $line;
-  while ( defined($line=<$fh>) ) {
-
-    $csv->parse($line) or do {
-      $dbh->rollback if $oldAutoCommit;
-      return "can't parse: ". $csv->error_input();
-    };
-
-    my @columns = $csv->fields();
-    #warn join('-',@columns);
-
-    my %row = ();
-    foreach my $field ( @fields ) {
-      $row{$field} = shift @columns;
-    }
-
-    if ( $row{custnum} && $row{agent_custid} ) {
-      dbh->rollback if $oldAutoCommit;
-      return "can't specify custnum with agent_custid $row{agent_custid}";
-    }
-
-    my %hash = ();
-    if ( $row{agent_custid} && $agentnum ) {
-      %hash = ( 'agent_custid' => $row{agent_custid},
-                'agentnum'     => $agentnum,
-              );
-    }
-
-    if ( $row{custnum} ) {
-      %hash = ( 'custnum' => $row{custnum} );
-    }
-
-    unless ( scalar(keys %hash) ) {
-      $dbh->rollback if $oldAutoCommit;
-      return "can't find customer without custnum or agent_custid and agentnum";
-    }
-
-    my $cust_main = qsearchs('cust_main', { %hash } );
-    unless ( $cust_main ) {
-      $dbh->rollback if $oldAutoCommit;
-      my $custnum = $row{custnum} || $row{agent_custid};
-      return "unknown custnum $custnum";
-    }
-
-    if ( $row{'amount'} > 0 ) {
-      my $error = $cust_main->charge($row{'amount'}, $row{'pkg'});
-      if ( $error ) {
-        $dbh->rollback if $oldAutoCommit;
-        return $error;
-      }
-      $imported++;
-    } elsif ( $row{'amount'} < 0 ) {
-      my $error = $cust_main->credit( sprintf( "%.2f", 0-$row{'amount'} ),
-                                      $row{'pkg'}                         );
-      if ( $error ) {
-        $dbh->rollback if $oldAutoCommit;
-        return $error;
-      }
-      $imported++;
-    } else {
-      #hmm?
-    }
-
-  }
-
-  $dbh->commit or die $dbh->errstr if $oldAutoCommit;
-
-  return "Empty file!" unless $imported;
-
-  ''; #no error
-
-}
-
 =item notify CUSTOMER_OBJECT TEMPLATE_NAME OPTIONS
 
 Deprecated.  Use event notification and message templates 
@@ -5763,8 +5664,11 @@ sub queueable_upgrade {
     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;
@@ -5790,12 +5694,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');
   }
 
 }
@@ -5808,10 +5720,13 @@ sub _upgrade_next_recnum {
   my $recnum = shift @$recnums;
   return $recnum if $recnum;
   my $tclass = 'FS::'.$table;
+  my $paycardtypecheck = ($table ne 'cust_pay_pending') ? q( OR paycardtype = 'Tokenized') : '';
   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$paycardtypecheck ) ".
+            ' ORDER BY '.$tclass->primary_key.' LIMIT 500';
   my $sth = $dbh->prepare($sql) or die $dbh->errstr;
   $sth->execute() or die $sth->errstr;
   my @recnums;