[freeside-commits] branch master updated. c91974c5178828304d723d15f0b6405d173fa707

Mark Wells mark at 420.am
Fri Jul 15 16:56:33 PDT 2016


The branch, master has been updated
       via  c91974c5178828304d723d15f0b6405d173fa707 (commit)
       via  522d56b651bee0d586fbb5daa3196042bc6a9d8e (commit)
      from  ad6c73ef3ac6288a8bf22a4adb15261ac22470b8 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit c91974c5178828304d723d15f0b6405d173fa707
Author: Mark Wells <mark at freeside.biz>
Date:   Fri Jul 15 16:11:53 2016 -0700

    use stored card type for payment search, #71291

diff --git a/httemplate/search/elements/cust_pay_or_refund.html b/httemplate/search/elements/cust_pay_or_refund.html
index 4ed297d..03aaedd 100755
--- a/httemplate/search/elements/cust_pay_or_refund.html
+++ b/httemplate/search/elements/cust_pay_or_refund.html
@@ -67,6 +67,15 @@ Examples:
                                     ],
                 'show_combined'  => 1,
 &>
+<%shared>
+# canonicalize the payby subtype string to an SQL-quoted list
+my %cardtype_of = (
+  'VisaMC'    => q['VISA card', 'MasterCard'],
+  'Amex'      => q['American Express card'],
+  'Discover'  => q['Discover card'],
+  'Maestro'   => q['Switch', 'Solo', 'Laser'],
+);  
+</%shared>
 <%init>
 
 my %opt = @_;
@@ -191,10 +200,8 @@ if ($opt{'show_card_type'}) {
   push @header, emt('Card Type');
   $align .= 'r';
   push @links, '';
-  push @fields, sub { 
-    (($_[0]->payby eq 'CARD') && ($_[0]->paymask !~ /N\/A/)) ? cardtype($_[0]->paymask) : ''
-  };
-  push @sort_fields, '';
+  push @fields, 'paycardtype';
+  push @sort_fields, 'paycardtype';
 }
 
 if ( $unapplied ) {
@@ -305,150 +312,32 @@ if ( $cgi->param('magic') ) {
     if ( $cgi->param('payby') ) {
 
       my @all_payby_search = ();
-      foreach my $payby ( $cgi->param('payby') ) {
-
-        $payby =~
-          /^(CARD|CHEK|BILL|CASH|PPAL|APPL|ANRD|PREP|WIRE|WEST|IDTP|EDI|MCRD|MCHK)(-(VisaMC|Amex|Discover|Maestro|Tokenized))?$/
-            or die "illegal payby $payby";
-
-        my $payby_search = "$table.payby = '$1'";
-
-        if ( $3 ) {
-
-          my $cardtype = $3;
-
-          my $similar_to = dbh->{Driver}->{Name} =~ /^mysql/i
-                             ? 'REGEXP' #doesn't behave exactly the same, but
-                                        #should work for our patterns
-                             : 'SIMILAR TO';
-
-          my $search;
-          if ( $cardtype eq 'VisaMC' ) {
-
-            #avoid posix regexes for portability
-            $search =
-              # Visa
-              " ( (     substring($table.payinfo from 1 for 1) = '4'     ".
-              #   is not Switch
-              "     AND substring($table.payinfo from 1 for 4) != '4936' ".
-              "     AND substring($table.payinfo from 1 for 6)           ".
-              "         NOT $similar_to '49030[2-9]'                        ".
-              "     AND substring($table.payinfo from 1 for 6)           ".
-              "         NOT $similar_to '49033[5-9]'                        ".
-              "     AND substring($table.payinfo from 1 for 6)           ".
-              "         NOT $similar_to '49110[1-2]'                        ".
-              "     AND substring($table.payinfo from 1 for 6)           ".
-              "         NOT $similar_to '49117[4-9]'                        ".
-              "     AND substring($table.payinfo from 1 for 6)           ".
-              "         NOT $similar_to '49118[1-2]'                        ".
-              "   )".
-              # MasterCard
-              "   OR substring($table.payinfo from 1 for 2) = '51' ".
-              "   OR substring($table.payinfo from 1 for 2) = '52' ".
-              "   OR substring($table.payinfo from 1 for 2) = '53' ".
-              "   OR substring($table.payinfo from 1 for 2) = '54' ".
-              "   OR substring($table.payinfo from 1 for 2) = '54' ".
-              "   OR substring($table.payinfo from 1 for 2) = '55' ".
-              "   OR substring($table.payinfo from 1 for 4) $similar_to '222[1-9]' ".
-              "   OR substring($table.payinfo from 1 for 3) $similar_to '22[3-9]' ".
-              "   OR substring($table.payinfo from 1 for 2) $similar_to '2[3-6]' ".
-              "   OR substring($table.payinfo from 1 for 3) $similar_to '27[0-1]' ".
-              "   OR substring($table.payinfo from 1 for 4) = '2720' ".
-              "   OR substring($table.payinfo from 1 for 3) = '2[2-7]x' ".
-              " ) ";
-
-          } elsif ( $cardtype eq 'Amex' ) {
-
-            $search =
-              " (    substring($table.payinfo from 1 for 2 ) = '34' ".
-              "   OR substring($table.payinfo from 1 for 2 ) = '37' ".
-              " ) ";
-
-          } elsif ( $cardtype eq 'Discover' ) {
-
-            my $country = $conf->config('countrydefault') || 'US';
-
-            $search =
-              " (    substring($table.payinfo from 1 for 4 ) = '6011'  ".
-              "   OR substring($table.payinfo from 1 for 3 ) = '60x'   ".
-              "   OR substring($table.payinfo from 1 for 2 ) = '65'    ".
-
-              # diner's 300-305 / 3095
-              "   OR substring($table.payinfo from 1 for 3 ) = '300'   ".
-              "   OR substring($table.payinfo from 1 for 3 ) = '301'   ".
-              "   OR substring($table.payinfo from 1 for 3 ) = '302'   ".
-              "   OR substring($table.payinfo from 1 for 3 ) = '303'   ".
-              "   OR substring($table.payinfo from 1 for 3 ) = '304'   ".
-              "   OR substring($table.payinfo from 1 for 3 ) = '305'   ".
-              "   OR substring($table.payinfo from 1 for 4 ) = '3095'  ".
-              "   OR substring($table.payinfo from 1 for 3 ) = '30x'   ".
-
-              # diner's 36, 38, 39
-              "   OR substring($table.payinfo from 1 for 2 ) = '36'    ".
-              "   OR substring($table.payinfo from 1 for 2 ) = '38'    ".
-              "   OR substring($table.payinfo from 1 for 2 ) = '39'    ".
-
-              "   OR substring($table.payinfo from 1 for 3 ) = '644'   ".
-              "   OR substring($table.payinfo from 1 for 3 ) = '645'   ".
-              "   OR substring($table.payinfo from 1 for 3 ) = '646'   ".
-              "   OR substring($table.payinfo from 1 for 3 ) = '647'   ".
-              "   OR substring($table.payinfo from 1 for 3 ) = '648'   ".
-              "   OR substring($table.payinfo from 1 for 3 ) = '649'   ".
-              "   OR substring($table.payinfo from 1 for 3 ) = '64x'   ".
-
-              # JCB cards in the 3528-3589 range identified as Discover inside US & territories (NOT Canada)
-              ( $country =~ /^(US|PR|VI|MP|PW|GU)$/
-               ?" OR substring($table.payinfo from 1 for 4 ) = '3528'  ".
-                " OR substring($table.payinfo from 1 for 4 ) = '3529'  ".
-                " OR substring($table.payinfo from 1 for 3 ) = '353'   ".
-                " OR substring($table.payinfo from 1 for 3 ) = '354'   ".
-                " OR substring($table.payinfo from 1 for 3 ) = '355'   ".
-                " OR substring($table.payinfo from 1 for 3 ) = '356'   ".
-                " OR substring($table.payinfo from 1 for 3 ) = '357'   ".
-                " OR substring($table.payinfo from 1 for 3 ) = '358'   ".
-                " OR substring($table.payinfo from 1 for 3 ) = '35x'   "
-               :""
-              ).
-
-              #China Union Pay processed as Discover in US, Mexico and Caribbean
-              ( $country =~ /^(US|MX|AI|AG|AW|BS|BB|BM|BQ|VG|KY|CW|DM|DO|GD|GP|JM|MQ|MS|BL|KN|LC|VC|MF|SX|TT|TC)$/
-               ?" OR substring($table.payinfo from 1 for 3 ) $similar_to '62[24-68x]'   "
-               :""
-              ).
-
-              " ) ";
-
-          } elsif ( $cardtype eq 'Maestro' ) {
-
-            $search =
-              " (    substring($table.payinfo from 1 for 2 ) = '63'     ".
-              "   OR substring($table.payinfo from 1 for 2 ) = '67'     ".
-              "   OR substring($table.payinfo from 1 for 6 ) = '564182' ".
-              "   OR substring($table.payinfo from 1 for 4 ) = '4936'   ".
-              "   OR substring($table.payinfo from 1 for 6 )            ".
-              "      $similar_to '49030[2-9]'                             ".
-              "   OR substring($table.payinfo from 1 for 6 )            ".
-              "      $similar_to '49033[5-9]'                             ".
-              "   OR substring($table.payinfo from 1 for 6 )            ".
-              "      $similar_to '49110[1-2]'                             ".
-              "   OR substring($table.payinfo from 1 for 6 )            ".
-              "      $similar_to '49117[4-9]'                             ".
-              "   OR substring($table.payinfo from 1 for 6 )            ".
-              "      $similar_to '49118[1-2]'                             ".
-              " ) ";
-
-          } elsif ( $cardtype eq 'Tokenized' ) {
-
-            $search = " substring($table.payinfo from 1 for 2 ) = '99' ";
+      foreach my $payby_string ( $cgi->param('payby') ) {
+
+        my $payby_search;
+
+        my ($payby, $subtype) = split('-', $payby_string);
+        # make sure it exists and is a transaction type
+        if ( FS::payby->payment_payby2longname($payby) ) {
+          $payby_search = "$table.payby = " . dbh->quote($payby);
+        } else {
+          die "illegal payby $payby_string";
+        }
+
+        if ( $subtype ) {
+
+          if ( $subtype eq 'Tokenized' ) {
+
+            $payby_search .= " AND substring($table.payinfo from 1 for 2 ) = '99' ";
+            # XXX should store the cardtype as 'Tokenized' in this case?
 
           } else {
-            die "unknown card type $cardtype";
-          }
 
-          my $masksearch = $search;
-          $masksearch =~ s/$table\.payinfo/$table.paymask/gi;
+            my $in_cardtype = $cardtype_of{$subtype}
+              or die "unknown card type $subtype";
+            $payby_search .= " AND $table.paycardtype IN($in_cardtype)";
 
-          $payby_search = "( $payby_search AND ( $search OR ( $table.paymask IS NOT NULL AND $masksearch ) ) )";
+          }
 
         }
 
@@ -610,6 +499,8 @@ if ( $cgi->param('magic') ) {
     'addl_from' => $addl_from,
   };
 
+warn Dumper \$sql_query;
+
 } else {
 
   #hmm... is this still used?

commit 522d56b651bee0d586fbb5daa3196042bc6a9d8e
Author: Mark Wells <mark at freeside.biz>
Date:   Fri Jul 15 15:50:27 2016 -0700

    rename cardtype to paycardtype

diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm
index 8307ee0..9074ae4 100644
--- a/FS/FS/Schema.pm
+++ b/FS/FS/Schema.pm
@@ -1693,7 +1693,7 @@ sub tables_hashref {
         'weight',          'int', 'NULL',        '', '', '', 
         'payby',          'char',     '',         4, '', '', 
         'payinfo',     'varchar', 'NULL',       512, '', '', 
-        'cardtype',    'varchar', 'NULL',   $char_d, '', '',
+        'paycardtype', 'varchar', 'NULL',   $char_d, '', '',
         'paycvv',      'varchar', 'NULL',       512, '', '', 
         'paymask',     'varchar', 'NULL',   $char_d, '', '', 
         #'paydate',   @date_type, '', '', 
@@ -2443,7 +2443,7 @@ sub tables_hashref {
         'usernum',         'int', 'NULL',      '', '', '',
         'payby',          'char',     '',       4, '', '',
         'payinfo',     'varchar', 'NULL',     512, '', '',
-        'cardtype',    'varchar', 'NULL',   $char_d, '', '',
+        'paycardtype', 'varchar', 'NULL',   $char_d, '', '',
         'paymask',     'varchar', 'NULL', $char_d, '', '', 
         'paydate',     'varchar', 'NULL',      10, '', '', 
         'paybatch',    'varchar', 'NULL', $char_d, '', '',#for auditing purposes
@@ -2501,7 +2501,7 @@ sub tables_hashref {
         'usernum',         'int', 'NULL',      '', '', '',
         'payby',          'char',     '',       4, '', '',
         'payinfo',     'varchar', 'NULL',     512, '', '',
-        'cardtype',    'varchar', 'NULL',   $char_d, '', '',
+        'paycardtype', 'varchar', 'NULL',   $char_d, '', '',
         'paymask',     'varchar', 'NULL', $char_d, '', '', 
         #'paydate' ?
         'paybatch',    'varchar', 'NULL', $char_d, '', '', #for auditing purposes.
@@ -3061,7 +3061,7 @@ sub tables_hashref {
                                                      # be index into payby
                                                      # table eventually
         'payinfo',      'varchar',   'NULL', 512, '', '', #see cust_main above
-        'cardtype',    'varchar', 'NULL',   $char_d, '', '',
+        'paycardtype',  'varchar', 'NULL',   $char_d, '', '',
         'paymask', 'varchar', 'NULL', $char_d, '', '', 
         'paybatch',     'varchar',   'NULL', $char_d, '', '', 
         'closed',    'char', 'NULL', 1, '', '', 
diff --git a/FS/FS/Upgrade.pm b/FS/FS/Upgrade.pm
index 3aa3e53..6f14cd2 100644
--- a/FS/FS/Upgrade.pm
+++ b/FS/FS/Upgrade.pm
@@ -422,7 +422,7 @@ sub upgrade_data {
     'cust_refund' => [],
     'banned_pay' => [],
 
-    #cardtype
+    #paycardtype
     'cust_payby' => [],
 
     #default namespace
diff --git a/FS/FS/cust_pay.pm b/FS/FS/cust_pay.pm
index 8e87745..e0a7143 100644
--- a/FS/FS/cust_pay.pm
+++ b/FS/FS/cust_pay.pm
@@ -97,7 +97,7 @@ Payment Type (See L<FS::payinfo_Mixin> for valid values)
 
 Payment Information (See L<FS::payinfo_Mixin> for data format)
 
-=item cardtype
+=item paycardtype
 
 Credit card type, if appropriate; autodetected.
 
@@ -1211,7 +1211,7 @@ sub _upgrade_data {  #class method
   }
 
   ###
-  # set cardtype
+  # set paycardtype
   ###
   $class->upgrade_set_cardtype;
 
diff --git a/FS/FS/cust_payby.pm b/FS/FS/cust_payby.pm
index 993bab5..facb9c8 100644
--- a/FS/FS/cust_payby.pm
+++ b/FS/FS/cust_payby.pm
@@ -115,7 +115,7 @@ paytype
 
 payip
 
-=item cardtype
+=item paycardtype
 
 The credit card type (deduced from the card number).
 
@@ -354,10 +354,11 @@ sub check {
       or return gettext('invalid_card'); # . ": ". $self->payinfo;
 
     my $cardtype = cardtype($payinfo);
-    $self->set('cardtype', $cardtype);
-    return gettext('unknown_card_type')
-      if $self->payinfo !~ /^99\d{14}$/ #token
-      && $cardtype eq "Unknown";
+    $cardtype = 'Tokenized' if $self->payinfo !~ /^99\d{14}$/; #token
+    
+    return gettext('unknown_card_type') if $cardtype eq "Unknown";
+    
+    $self->set('paycardtype', $cardtype);
 
     unless ( $ignore_banned_card ) {
       my $ban = FS::banned_pay->ban_search( %{ $self->_banned_pay_hashref } );
@@ -453,9 +454,9 @@ sub check {
     # either ignoring invalid cards, or we can't decrypt the payinfo, but
     # try to detect the card type anyway. this never returns failure, so
     # the contract of $ignore_invalid_cards is maintained.
-    $self->set('cardtype', cardtype($self->paymask));
+    $self->set('paycardtype', cardtype($self->paymask));
   } else {
-    $self->set('cardtype', '');
+    $self->set('paycardtype', '');
   }
 
 #  } elsif ( $self->payby eq 'PREPAY' ) {
@@ -539,11 +540,14 @@ sub check_payinfo_cardtype {
   my $payinfo = $self->payinfo;
   $payinfo =~ s/\D//g;
 
-  return '' if $payinfo =~ /^99\d{14}$/; #token
+  if ( $payinfo =~ /^99\d{14}$/ ) {
+    $self->set('paycardtype', 'Tokenized');
+    return '';
+  }
 
   my %bop_card_types = map { $_=>1 } values %{ card_types() };
   my $cardtype = cardtype($payinfo);
-  $self->set('cardtype', $cardtype);
+  $self->set('paycardtype', $cardtype);
 
   return "$cardtype not accepted" unless $bop_card_types{$cardtype};
 
@@ -619,7 +623,7 @@ sub label {
   my $self = shift;
 
   my $name = $self->payby =~ /^(CARD|DCRD)$/
-              && $self->cardtype || FS::payby->shortname($self->payby);
+              && $self->paycardtype || FS::payby->shortname($self->payby);
 
   ( $self->payby =~ /^(CARD|CHEK)$/  ? $weight{$self->weight}. ' automatic '
                                      : 'Manual '
diff --git a/FS/FS/cust_refund.pm b/FS/FS/cust_refund.pm
index ee144c1..4d2baa5 100644
--- a/FS/FS/cust_refund.pm
+++ b/FS/FS/cust_refund.pm
@@ -82,7 +82,7 @@ Payment Type (See L<FS::payinfo_Mixin> for valid payby values)
 
 Payment Information (See L<FS::payinfo_Mixin> for data format)
 
-=item cardtype
+=item paycardtype
 
 Detected credit card type, if appropriate; autodetected.
 
diff --git a/FS/FS/payinfo_Mixin.pm b/FS/FS/payinfo_Mixin.pm
index b32f13b..a61125e 100644
--- a/FS/FS/payinfo_Mixin.pm
+++ b/FS/FS/payinfo_Mixin.pm
@@ -194,9 +194,12 @@ sub payinfo_check {
     or return "Illegal payby: ". $self->payby;
 
   if ( $self->payby eq 'CARD' && ! $self->is_encrypted($self->payinfo) ) {
+
     my $payinfo = $self->payinfo;
     my $cardtype = cardtype($payinfo);
-    $self->set('cardtype', $cardtype);
+    $cardtype = 'Tokenized' if $payinfo !~ /^99\d{14}$/;
+    $self->set('paycardtype', $cardtype);
+
     if ( $ignore_masked_payinfo and $self->mask_payinfo eq $self->payinfo ) {
       # allow it
     } else {
@@ -207,8 +210,7 @@ sub payinfo_check {
           or return "Illegal (mistyped?) credit card number (payinfo)";
         $self->payinfo($1);
         validate($self->payinfo) or return "Illegal credit card number";
-        return "Unknown card type" if $self->payinfo !~ /^99\d{14}$/ #token
-                                   && $cardtype eq "Unknown";
+        return "Unknown card type" if $cardtype eq "Unknown";
       } else {
         $self->payinfo('N/A'); #???
       }
@@ -216,9 +218,9 @@ sub payinfo_check {
   } else {
     if ( $self->payby eq 'CARD' and $self->paymask ) {
       # if we can't decrypt the card, at least detect the cardtype
-      $self->set('cardtype', cardtype($self->paymask));
+      $self->set('paycardtype', cardtype($self->paymask));
     } else {
-      $self->set('cardtype', '');
+      $self->set('paycardtype', '');
     }
     if ( $self->is_encrypted($self->payinfo) ) {
       #something better?  all it would cause is a decryption error anyway?
@@ -415,8 +417,8 @@ sub paydate_epoch_sql {
 
 =item upgrade_set_cardtype
 
-Find all records with a credit card payment type and no cardtype, and
-replace them in order to set their cardtype.
+Find all records with a credit card payment type and no paycardtype, and
+replace them in order to set their paycardtype.
 
 =cut
 
@@ -427,7 +429,7 @@ sub upgrade_set_cardtype {
   local $ignore_masked_payinfo = 1;
   my $search = FS::Cursor->new({
     table     => $class->table,
-    extra_sql => q[ WHERE payby IN('CARD','DCRD') AND cardtype IS NULL ],
+    extra_sql => q[ WHERE payby IN('CARD','DCRD') AND paycardtype IS NULL ],
   });
   while (my $record = $search->fetch) {
     my $error = $record->replace;

-----------------------------------------------------------------------

Summary of changes:
 FS/FS/Schema.pm                                    |    8 +-
 FS/FS/Upgrade.pm                                   |    2 +-
 FS/FS/cust_pay.pm                                  |    4 +-
 FS/FS/cust_payby.pm                                |   24 +--
 FS/FS/cust_refund.pm                               |    2 +-
 FS/FS/payinfo_Mixin.pm                             |   18 +-
 httemplate/search/elements/cust_pay_or_refund.html |  179 ++++----------------
 7 files changed, 67 insertions(+), 170 deletions(-)




More information about the freeside-commits mailing list