fix self-service error on change package with BILL customers and selfservice-realtime...
[freeside.git] / FS / FS / ClientAPI / MyAccount.pm
index 88266da..a580991 100644 (file)
@@ -379,6 +379,8 @@ sub access_info {
       $conf->exists('ticket_system-selfservice_edit_subject') && 
       $cust_main->edit_subject;
 
+  $info->{'timeout'} = $conf->config('selfservice-timeout') || 3600;
+
   return { %$info,
            'custnum'       => $custnum,
            'access_pkgnum' => $session->{'pkgnum'},
@@ -830,7 +832,7 @@ sub payment_info {
 
       'save_unchecked' => $conf->exists('selfservice-save_unchecked'),
 
-      'credit_card_surcharge_percentage' => $conf->config('credit-card-surcharge-percentage'),
+      'credit_card_surcharge_percentage' => scalar($conf->config('credit-card-surcharge-percentage')),
     };
 
   }
@@ -1009,7 +1011,7 @@ sub validate_payment {
 
   { 
     'cust_main'      => $cust_main, #XXX or just custnum??
-    'amount'         => $amount,
+    'amount'         => sprintf('%.2f', $amount),
     'payby'          => $payby,
     'payinfo'        => $payinfo,
     'paymask'        => $cust_main->mask_payinfo( $payby, $payinfo ),
@@ -1252,6 +1254,50 @@ sub realtime_collect {
   return { 'error' => '', amount => $amount, %$error };
 }
 
+sub start_thirdparty {
+  my $p = shift;
+  my $session = _cache->get($p->{'session_id'})
+    or return { 'error' => "Can't resume session" }; #better error message
+  my $custnum = $session->{'custnum'};
+  my $cust_main = FS::cust_main->by_key($custnum);
+  
+  my $amount = $p->{'amount'}
+    or return { error => 'no amount' };
+
+  my $result = $cust_main->create_payment(
+    'method'      => $p->{'method'},
+    'amount'      => $p->{'amount'},
+    'pkgnum'      => $session->{'pkgnum'},
+    'session_id'  => $p->{'session_id'},
+  );
+  
+  if ( ref($result) ) { # hashref or error
+    return $result;
+  } else {
+    return { error => $result };
+  }
+}
+
+sub finish_thirdparty {
+  my $p = shift;
+  my $session_id = delete $p->{'session_id'};
+  my $session = _cache->get($session_id)
+    or return { 'error' => "Can't resume session" };
+  my $custnum = $session->{'custnum'};
+  my $cust_main = FS::cust_main->by_key($custnum);
+
+  if ( $p->{_cancel} ) {
+    # customer backed out of making a payment
+    return $cust_main->cancel_payment( $session_id );
+  }
+  my $result = $cust_main->execute_payment( $session_id, %$p );
+  if ( ref($result) ) {
+    return $result;
+  } else {
+    return { error => $result };
+  }
+}
+
 sub process_payment_order_pkg {
   my $p = shift;
 
@@ -2257,6 +2303,11 @@ sub change_pkg {
   my $cust_pkg = qsearchs('cust_pkg', { 'pkgnum' => $p->{pkgnum} } )
     or return { 'error' => "unknown package $p->{pkgnum}" };
 
+  #if someone does need self-service package change of suspended packages,
+  # figure out how to be more discriminating
+  return { error=>"Can't change a suspended package", pkgnum=>$cust_pkg->pkgnum}
+    if $cust_pkg->status eq 'suspended';
+
   my @newpkg;
   my $error = FS::cust_pkg::order( $custnum,
                                    [$p->{pkgpart}],
@@ -2267,7 +2318,7 @@ sub change_pkg {
   my $conf = new FS::Conf;
   if ( $conf->exists('signup_server-realtime') ) {
 
-    my $bill_error = _do_bop_realtime( $cust_main, $status );
+    my $bill_error = _do_bop_realtime( $cust_main, $status, 'no_credit'=>1 );
 
     if ($bill_error) {
       $newpkg[0]->suspend;
@@ -2339,25 +2390,32 @@ sub order_recharge {
 }
 
 sub _do_bop_realtime {
-  my ($cust_main, $status) = (shift, shift);
+  my ($cust_main, $status, %opt) = @_;
 
     my $old_balance = $cust_main->balance;
 
     my $bill_error =    $cust_main->bill
-                     || $cust_main->apply_payments_and_credits
-                     || $cust_main->realtime_collect('selfservice' => 1);
+                     || $cust_main->apply_payments_and_credits;
+
+    $bill_error ||= $cust_main->realtime_collect('selfservice' => 1)
+      if $cust_main->payby =~ /^(CARD|CHEK)$/;
 
     if (    $cust_main->balance > $old_balance
          && $cust_main->balance > 0
-         && ( $cust_main->payby !~ /^(BILL|DCRD|DCHK)$/ ?
-              1 : $status eq 'suspended' ) ) {
-      #this makes sense.  credit is "un-doing" the invoice
-      my $conf = new FS::Conf;
-      $cust_main->credit( sprintf("%.2f", $cust_main->balance - $old_balance ),
-                          'self-service decline',
-                          'reason_type' => $conf->config('signup_credit_type'),
-                        );
-      $cust_main->apply_credits( 'order' => 'newest' );
+         && ( $cust_main->payby !~ /^(BILL|DCRD|DCHK)$/
+                || $status eq 'suspended'
+            )
+       )
+    {
+      unless ( $opt{'no_credit'} ) {
+        #this makes sense.  credit is "un-doing" the invoice
+        my $conf = new FS::Conf;
+        $cust_main->credit( sprintf("%.2f", $cust_main->balance-$old_balance ),
+                            'self-service decline',
+                            reason_type=>$conf->config('signup_credit_type'),
+                          );
+        $cust_main->apply_credits( 'order' => 'newest' );
+      }
 
       return { 'error' => '_decline', 'bill_error' => $bill_error };
     }
@@ -2755,13 +2813,16 @@ sub myaccount_passwd {
   } )
     or return { 'error' => "Service not found" };
 
-  if ( exists($p->{'old_password'}) ) {
-    return { 'error' => "Incorrect password." }
-      unless $svc_acct->check_password($p->{'old_password'});
-  }
+  my $error = '';
+
+  my $conf = new FS::Conf;
+  $error = 'Password too short.'
+    if length($p->{'new_password'}) < ($conf->config('passwordmin') || 6);
+  $error = 'Password too long.'
+    if length($p->{'new_password'}) > ($conf->config('passwordmax') || 8);
 
   $svc_acct->set_password($p->{'new_password'});
-  my $error = $svc_acct->replace();
+  $error ||= $svc_acct->replace();
 
   my($label, $value) = $svc_acct->cust_svc->label;