ticket 1568 config options for new echeck fields and addition to selfservice interface
[freeside.git] / FS / FS / ClientAPI / MyAccount.pm
index 8b6a466..9ee770b 100644 (file)
@@ -9,6 +9,7 @@ use Business::CreditCard;
 use Time::Duration;
 use FS::CGI qw(small_custview); #doh
 use FS::UI::Web;
+use FS::UI::bytecount;
 use FS::Conf;
 use FS::Record qw(qsearch qsearchs);
 use FS::Msgcat qw(gettext);
@@ -22,6 +23,7 @@ use FS::cust_main;
 use FS::cust_bill;
 use FS::cust_main_county;
 use FS::cust_pkg;
+use FS::payby;
 use HTML::Entities;
 
 #false laziness with FS::cust_main
@@ -236,6 +238,14 @@ sub payment_info {
 
       'card_types' => card_types(),
 
+      'paytypes' => [ @FS::cust_main::paytypes ],
+
+      'stateid_label' => FS::Msgcat::_gettext('stateid'),
+      'stateid_state_label' => FS::Msgcat::_gettext('stateid_state'),
+
+      'show_ss'  => $conf->exists('show_ss'),
+      'show_stateid' => $conf->exists('show_stateid'),
+      'show_paystate' => $conf->exists('show_bankstate'),
     };
 
   }
@@ -259,6 +269,7 @@ sub payment_info {
   $return{$_} = $cust_main->get($_) for qw(address1 address2 city state zip);
 
   $return{payby} = $cust_main->payby;
+  $return{stateid_state} = $cust_main->stateid_state;
 
   if ( $cust_main->payby =~ /^(CARD|DCRD)$/ ) {
     $return{card_type} = cardtype($cust_main->payinfo);
@@ -268,6 +279,15 @@ sub payment_info {
 
   }
 
+  if ( $cust_main->payby =~ /^(CHEK|DCHK)$/ ) {
+    my ($payinfo1, $payinfo2) = split '@', $cust_main->payinfo;
+    $return{payinfo1} = $payinfo1;
+    $return{payinfo2} = $payinfo2;
+    $return{paytype}  = $cust_main->paytype;
+    $return{paystate} = $cust_main->paystate;
+
+  }
+
   #doubleclick protection
   my $_date = time;
   $return{paybatch} = "webui-MyAccount-$_date-$$-". rand() * 2**32;
@@ -302,19 +322,23 @@ sub process_payment {
     or return { 'error' => gettext('illegal_text'). " paybatch: ". $p->{'paybatch'} };
   my $paybatch = $1;
 
+  $p->{'payby'} =~ /^([A-Z]{4})$/
+    or return { 'error' => "illegal_payby " . $p->{'payby'} };
+  my $payby = $1;
+
   my $payinfo;
   my $paycvv = '';
-  #if ( $payby eq 'CHEK' ) {
-  #
-  #  $p->{'payinfo1'} =~ /^(\d+)$/
-  #    or return { 'error' => "illegal account number ". $p->{'payinfo1'} };
-  #  my $payinfo1 = $1;
-  #   $p->{'payinfo2'} =~ /^(\d+)$/
-  #    or return { 'error' => "illegal ABA/routing number ". $p->{'payinfo2'} };
-  #  my $payinfo2 = $1;
-  #  $payinfo = $payinfo1. '@'. $payinfo2;
-  # 
-  #} elsif ( $payby eq 'CARD' ) {
+  if ( $payby eq 'CHEK' || $payby eq 'DCHK' ) {
+  
+    $p->{'payinfo1'} =~ /^(\d+)$/
+      or return { 'error' => "illegal account number ". $p->{'payinfo1'} };
+    my $payinfo1 = $1;
+     $p->{'payinfo2'} =~ /^(\d+)$/
+      or return { 'error' => "illegal ABA/routing number ". $p->{'payinfo2'} };
+    my $payinfo2 = $1;
+    $payinfo = $payinfo1. '@'. $payinfo2;
+   
+  } elsif ( $payby eq 'CARD' || $payby eq 'DCRD' ) {
    
     $payinfo = $p->{'payinfo'};
     $payinfo =~ s/\D//g;
@@ -326,33 +350,35 @@ sub process_payment {
     return { 'error' => gettext('unknown_card_type') }
       if cardtype($payinfo) eq "Unknown";
 
-    if ( defined $cust_main->dbdef_table->column('paycvv') ) {
-      if ( length($p->{'paycvv'} ) ) {
-        if ( cardtype($payinfo) eq 'American Express card' ) {
-          $p->{'paycvv'} =~ /^(\d{4})$/
-            or return { 'error' => "CVV2 (CID) for American Express cards is four digits." };
-          $paycvv = $1;
-        } else {
-          $p->{'paycvv'} =~ /^(\d{3})$/
-            or return { 'error' => "CVV2 (CVC2/CID) is three digits." };
-          $paycvv = $1;
-        }
+    if ( length($p->{'paycvv'}) && $p->{'paycvv'} !~ /^\s*$/ ) {
+      if ( cardtype($payinfo) eq 'American Express card' ) {
+        $p->{'paycvv'} =~ /^\s*(\d{4})\s*$/
+          or return { 'error' => "CVV2 (CID) for American Express cards is four digits." };
+        $paycvv = $1;
+      } else {
+        $p->{'paycvv'} =~ /^\s*(\d{3})\s*$/
+          or return { 'error' => "CVV2 (CVC2/CID) is three digits." };
+        $paycvv = $1;
       }
     }
   
-  #} else {
-  #  die "unknown payby $payby";
-  #}
+  } else {
+    die "unknown payby $payby";
+  }
 
-  my $error = $cust_main->realtime_bop( 'CC', $p->{'amount'},
+  my %payby2fields = (
+    'CARD' => [ qw( paystart_month paystart_year payissue address1 address2 city state zip payip ) ],
+    'CHEK' => [ qw( ss paytype paystate stateid stateid_state payip ) ],
+  );
+
+  my $error = $cust_main->realtime_bop( $FS::payby::payby2bop{$payby}, $p->{'amount'},
     'quiet'    => 1,
     'payinfo'  => $payinfo,
     'paydate'  => $p->{'year'}. '-'. $p->{'month'}. '-01',
     'payname'  => $payname,
     'paybatch' => $paybatch,
     'paycvv'   => $paycvv,
-    map { $_ => $p->{$_} } qw( paystart_month paystart_year payissue payip
-                               address1 address2 city state zip )
+    map { $_ => $p->{$_} } @{ $payby2fields{$payby} }
   );
   return { 'error' => $error } if $error;
 
@@ -360,11 +386,19 @@ sub process_payment {
 
   if ( $p->{'save'} ) {
     my $new = new FS::cust_main { $cust_main->hash };
-    $new->set( $_ => $p->{$_} )
-      foreach qw( payname paystart_month paystart_year payissue payip
-                  address1 address2 city state zip payinfo );
+    if ($payby eq 'CARD' || $payby eq 'DCRD') {
+      $new->set( $_ => $p->{$_} )
+        foreach qw( payname paystart_month paystart_year payissue payip
+                    address1 address2 city state zip payinfo );
+      $new->set( 'payby' => $p->{'auto'} ? 'CARD' : 'DCRD' );
+    } elsif ($payby eq 'CHEK' || $payby eq 'DCHK') {
+      $new->set( $_ => $p->{$_} )
+        foreach qw( payname payip paytype paystate
+                    stateid stateid_state );
+      $new->set( 'payinfo' => $payinfo );
+      $new->set( 'payby' => $p->{'auto'} ? 'CHEK' : 'DCHK' );
+    }
     $new->set( 'paydate' => $p->{'year'}. '-'. $p->{'month'}. '-01' );
-    $new->set( 'payby' => $p->{'auto'} ? 'CARD' : 'DCRD' );
     my $error = $new->replace($cust_main);
     return { 'error' => $error } if $error;
     $cust_main = $new;
@@ -404,11 +438,11 @@ sub process_prepay {
            'seconds'   => $seconds,
            'duration'  => duration_exact($seconds),
            'upbytes'   => $upbytes,
-           'upload'    => FS::UI::Web::bytecount_unexact($upbytes),
+           'upload'    => FS::UI::bytecount::bytecount_unexact($upbytes),
            'downbytes' => $downbytes,
-           'download'  => FS::UI::Web::bytecount_unexact($downbytes),
+           'download'  => FS::UI::bytecount::bytecount_unexact($downbytes),
            'totalbytes'=> $totalbytes,
-           'totalload' => FS::UI::Web::bytecount_unexact($totalbytes),
+           'totalload' => FS::UI::bytecount::bytecount_unexact($totalbytes),
          };
 
 }
@@ -581,14 +615,14 @@ sub list_svcs {
                             'username'  => $svc_x->username,
                             'email'     => $svc_x->email,
                             'seconds'   => $svc_x->seconds,
-                            'upbytes'   => $svc_x->upbytes,
-                            'downbytes' => $svc_x->downbytes,
-                            'totalbytes'=> $svc_x->totalbytes,
+                            'upbytes'   => FS::UI::bytecount::display_bytecount($svc_x->upbytes),
+                            'downbytes' => FS::UI::bytecount::display_bytecount($svc_x->downbytes),
+                            'totalbytes'=> FS::UI::bytecount::display_bytecount($svc_x->totalbytes),
                             'recharge_amount' => $part_pkg->option('recharge_amount', 1),
                             'recharge_seconds' => $part_pkg->option('recharge_seconds', 1),
-                            'recharge_upbytes' => $part_pkg->option('recharge_upbytes', 1),
-                            'recharge_downbytes' => $part_pkg->option('recharge_downbytes', 1),
-                            'recharge_totalbytes' => $part_pkg->option('recharge_totalbytes', 1),
+                            'recharge_upbytes' => FS::UI::bytecount::display_bytecount($part_pkg->option('recharge_upbytes', 1)),
+                            'recharge_downbytes' => FS::UI::bytecount::display_bytecount($part_pkg->option('recharge_downbytes', 1)),
+                            'recharge_totalbytes' => FS::UI::bytecount::display_bytecount($part_pkg->option('recharge_totalbytes', 1)),
                             # more...
                           };
                         }
@@ -612,7 +646,8 @@ sub list_svc_usage {
 
   my $freq   = $svc_acct->cust_svc->cust_pkg->part_pkg->freq;
   my $start  = $svc_acct->cust_svc->cust_pkg->setup;
-  my $end    = $svc_acct->cust_svc->cust_pkg->bill; # or time?
+  #my $end    = $svc_acct->cust_svc->cust_pkg->bill; # or time?
+  my $end    = time;
 
   unless($p->{beginning}){
     $p->{beginning} = $svc_acct->cust_svc->cust_pkg->last_bill;
@@ -713,7 +748,7 @@ sub order_pkg {
     $svcpart ||= $cust_pkg->part_pkg->svcpart($svcdb);
 
     my %fields = (
-      'svc_acct'     => [ qw( username _password sec_phrase popnum ) ],
+      'svc_acct'     => [ qw( username domsvc _password sec_phrase popnum ) ],
       'svc_domain'   => [ qw( domain ) ],
       'svc_external' => [ qw( id title ) ],
     );
@@ -877,8 +912,7 @@ sub _do_bop_realtime {
 
     my $bill_error = $cust_main->bill;
 
-    $cust_main->apply_payments;
-    $cust_main->apply_credits;
+    $cust_main->apply_payments_and_credits;
     $bill_error = $cust_main->collect('realtime' => 1);
 
     if (    $cust_main->balance > $old_balance