RT#38881: BILL illegal payby in 4.x [update_payby]
[freeside.git] / FS / FS / ClientAPI / MyAccount.pm
index d6fa865..685821b 100644 (file)
@@ -11,7 +11,7 @@ use Digest::SHA qw(sha512_hex);
 use Date::Format;
 use Time::Duration;
 use Time::Local qw(timelocal_nocheck);
-use Business::CreditCard;
+use Business::CreditCard 0.35;
 use HTML::Entities;
 use Text::CSV_XS;
 use Spreadsheet::WriteExcel;
@@ -1627,6 +1627,50 @@ sub insert_payby {
   
 }
 
+sub update_payby {
+  my $p = shift;
+
+  my($context, $session, $custnum) = _custoragent_session_custnum($p);
+  return { 'error' => $session } if $context eq 'error';
+
+  my $cust_payby = qsearchs('cust_payby', {
+                              'custnum'      => $custnum,
+                              'custpaybynum' => $p->{'custpaybynum'},
+                           })
+    or return { 'error' => 'unknown custpaybynum '. $p->{'custpaybynum'} };
+
+  foreach my $field (
+    qw( weight payby payinfo paycvv paydate payname paystate paytype payip )
+  ) {
+    next unless exists($p->{$field});
+    $cust_payby->set($field,$p->{$field});
+  }
+
+  my $error = $cust_payby->replace;
+  if ( $error ) {
+    return { 'error' => $error };
+  } else {
+    return { 'custpaybynum' => $cust_payby->custpaybynum };
+  }
+  
+}
+
+sub verify_payby {
+  my $p = shift;
+
+  my($context, $session, $custnum) = _custoragent_session_custnum($p);
+  return { 'error' => $session } if $context eq 'error';
+
+  my $cust_payby = qsearchs('cust_payby', {
+                              'custnum'      => $custnum,
+                              'custpaybynum' => $p->{'custpaybynum'},
+                           })
+    or return { 'error' => 'unknown custpaybynum '. $p->{'custpaybynum'} };
+
+  return { 'error' => $cust_payby->verify };
+  
+}
+
 sub delete_payby {
   my $p = shift;
 
@@ -1819,6 +1863,7 @@ sub list_svcs {
   #              @svc_x;
 
   my @svcs; # stuff to return to the client
+  my %bytes_used_total; # for _used columns only
   foreach my $cust_svc (@cust_svc) {
     my $svc_x = $cust_svc->svc_x;
     my($label, $value) = $cust_svc->label;
@@ -1840,6 +1885,24 @@ sub list_svcs {
 
     # would it make sense to put this in a svc_* method?
 
+    if (!$hide_usage and grep(/^$svcdb$/, qw(svc_acct svc_broadband)) and $part_svc->part_export_usage) {
+      my $last_bill = $cust_pkg->last_bill || 0;
+      my $now = time;
+      my $up_used = $cust_svc->attribute_since_sqlradacct($last_bill,$now,'AcctInputOctets');
+      my $down_used = $cust_svc->attribute_since_sqlradacct($last_bill,$now,'AcctOutputOctets');
+      %hash = (
+        %hash,
+        'seconds_used'    => $cust_svc->seconds_since_sqlradacct($last_bill,$now),
+        'upbytes_used'    => display_bytecount($up_used),
+        'downbytes_used'  => display_bytecount($down_used),
+        'totalbytes_used' => display_bytecount($up_used + $down_used)
+      );
+      $bytes_used_total{'seconds_used'} += $hash{'seconds_used'};
+      $bytes_used_total{'upbytes_used'} += $up_used;
+      $bytes_used_total{'downbytes_used'} += $down_used;
+      $bytes_used_total{'totalbytes_used'} += $up_used + $down_used;
+    }
+
     if ( $svcdb eq 'svc_acct' ) {
       foreach (qw(username email finger seconds)) {
         $hash{$_} = $svc_x->$_;
@@ -1912,12 +1975,19 @@ sub list_svcs {
     push @svcs, \%hash;
   } # foreach $cust_svc
 
+  foreach my $field (keys %bytes_used_total) {
+    if ($field =~ /bytes/) {
+      $bytes_used_total{$field} = display_bytecount($bytes_used_total{$field});
+    }
+  }
+
   return { 
     'svcnum'   => $session->{'svcnum'},
     'custnum'  => $custnum,
     'date_format' => $conf->config('date_format') || '%m/%d/%Y',
     'view_usage_nodomain' => $conf->exists('selfservice-view_usage_nodomain'),
     'svcs'     => \@svcs,
+    'bytes_used_total' => \%bytes_used_total,
     'usage_pools' => [
       map { $usage_pools{$_} }
       sort { $a cmp $b }
@@ -2410,7 +2480,7 @@ sub order_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, 'collect'=>$p->{run_bill_events} );
 
     if ($bill_error) {
       $cust_pkg->cancel('quiet'=>1);
@@ -2565,6 +2635,12 @@ sub _do_bop_realtime {
     return { 'error' => '_decline', 'bill_error' => $bill_error };
   }
 
+  if ( $opt{'collect'} ) {
+    my $collect_error = $cust_main->collect();
+    return { 'error' => '_decline', 'bill_error' => $collect_error }
+     if $collect_error; #?
+  }
+
   '';
 }
 
@@ -3605,11 +3681,6 @@ sub adjust_ticket_priority {
   my($context, $session, $custnum) = _custoragent_session_custnum($p);
   return { 'error' => $session } if $context eq 'error';
 
-  # temporary instrumentation for RT#39536
-    local $DEBUG = 1;
-    local $FS::TicketSystem::RT_Internal::DEBUG = 1;
-    warn "[adjust_ticket_priority]\n" . Dumper($p->{'values'}) . "\n\n";
-
 #  warn "$me adjust_ticket_priority: initializing ticket system\n" if $DEBUG;
 #  FS::TicketSystem->init;
   my $ss_priority = FS::TicketSystem->selfservice_priority;