prepaid card recharge
authorivan <ivan>
Wed, 8 Jun 2005 09:03:06 +0000 (09:03 +0000)
committerivan <ivan>
Wed, 8 Jun 2005 09:03:06 +0000 (09:03 +0000)
20 files changed:
FS/FS/ClientAPI/MyAccount.pm
FS/FS/Conf.pm
FS/FS/cust_main.pm
FS/FS/svc_acct.pm
fs_selfservice/FS-SelfService/SelfService.pm
fs_selfservice/FS-SelfService/cgi/agent_delete_svc.html
fs_selfservice/FS-SelfService/cgi/delete_svc.html
fs_selfservice/FS-SelfService/cgi/make_payment.html
fs_selfservice/FS-SelfService/cgi/myaccount.html
fs_selfservice/FS-SelfService/cgi/myaccount_menu.html
fs_selfservice/FS-SelfService/cgi/payment_results.html
fs_selfservice/FS-SelfService/cgi/process_svc_acct.html
fs_selfservice/FS-SelfService/cgi/process_svc_external.html
fs_selfservice/FS-SelfService/cgi/provision.html
fs_selfservice/FS-SelfService/cgi/provision_svc_acct.html
fs_selfservice/FS-SelfService/cgi/recharge_prepay.html [new file with mode: 0644]
fs_selfservice/FS-SelfService/cgi/recharge_results.html [new file with mode: 0644]
fs_selfservice/FS-SelfService/cgi/selfservice.cgi
fs_selfservice/FS-SelfService/cgi/view_invoice.html
httemplate/view/svc_acct.cgi

index 4789733..60d1f64 100644 (file)
@@ -6,6 +6,7 @@ use subs qw(_cache);
 use Digest::MD5 qw(md5_hex);
 use Date::Format;
 use Business::CreditCard;
+use Time::Duration;
 use FS::CGI qw(small_custview); #doh
 use FS::Conf;
 use FS::Record qw(qsearch qsearchs);
@@ -135,12 +136,16 @@ sub customer_info {
     $return{'postal_invoicing'} =
       0 < ( grep { $_ eq 'POST' } $cust_main->invoicing_list );
 
-  } else { #no customer record
+  } elsif ( $session->{'svcnum'} ) { #no customer record
 
     my $svc_acct = qsearchs('svc_acct', { 'svcnum' => $session->{'svcnum'} } )
       or die "unknown svcnum";
     $return{name} = $svc_acct->email;
 
+  } else {
+
+    return { 'error' => 'Expired session' }; #XXX redirect to login w/this err!
+
   }
 
   return { 'error'          => '',
@@ -357,6 +362,36 @@ sub process_payment {
 
 }
 
+sub process_prepay {
+
+  my $p = shift;
+
+  my $session = _cache->get($p->{'session_id'})
+    or return { 'error' => "Can't resume session" }; #better error message
+
+  my %return;
+
+  my $custnum = $session->{'custnum'};
+
+  my $cust_main = qsearchs('cust_main', { 'custnum' => $custnum } )
+    or return { 'error' => "unknown custnum $custnum" };
+
+  my( $amount, $seconds ) = ( 0, 0 );
+  my $error = $cust_main->recharge_prepay( $p->{'prepaid_cardnum'},
+                                           \$amount,
+                                           \$seconds
+                                         );
+
+  return { 'error' => $error } if $error;
+
+  return { 'error'    => '',
+           'amount'   => $amount,
+           'seconds'  => $seconds,
+           'duration' => duration_exact($seconds),
+         };
+
+}
+
 sub invoice {
   my $p = shift;
   my $session = _cache->get($p->{'session_id'})
index ea2785b..a1fdd03 100644 (file)
@@ -1531,6 +1531,13 @@ httemplate/docs/config.html
     'type'        => 'checkbox',
   },
 
+  {
+    'key'         => 'svc_acct-usage_unsuspend',
+    'section'     => 'billing',
+    'description' => 'Unuspends the package an account belongs to when svc_acct.seconds is incremented from 0 or below to a positive value (accounts with an empty seconds value are ignored).  Typically used in conjunction with prepaid packages and freeside-sqlradius-radacctd.',
+    'type'        => 'checkbox',
+  },
+
 );
 
 1;
index 1edd319..775523a 100644 (file)
@@ -1,7 +1,7 @@
 package FS::cust_main;
 
 use strict;
-use vars qw( @ISA @EXPORT_OK $DEBUG $conf @encrypted_fields
+use vars qw( @ISA @EXPORT_OK $DEBUG $me $conf @encrypted_fields
              $import $skip_fuzzyfiles );
 use vars qw( $realtime_bop_decline_quiet ); #ugh
 use Safe;
@@ -51,7 +51,7 @@ use FS::Msgcat qw(gettext);
 $realtime_bop_decline_quiet = 0;
 
 $DEBUG = 0;
-#$DEBUG = 1;
+$me = '[FS::cust_main]';
 
 $import = 0;
 $skip_fuzzyfiles = 0;
@@ -349,33 +349,21 @@ sub insert {
   local $FS::UID::AutoCommit = 0;
   my $dbh = dbh;
 
-  my $prepay_credit = '';
-  my $seconds = 0;
+  my $prepay_identifier = '';
+  my( $amount, $seconds ) = ( 0, 0 );
   if ( $self->payby eq 'PREPAY' ) {
+
     $self->payby('BILL');
-    $prepay_credit = qsearchs(
-      'prepay_credit',
-      { 'identifier' => $self->payinfo },
-      '',
-      'FOR UPDATE'
-    );
-    unless ( $prepay_credit ) {
-      $dbh->rollback if $oldAutoCommit;
-      return "Invalid prepaid card: ". $self->payinfo;
-    }
-    $seconds = $prepay_credit->seconds;
-    if ( $prepay_credit->agentnum ) {
-      if ( $self->agentnum && $self->agentnum != $prepay_credit->agentnum ) {
-        $dbh->rollback if $oldAutoCommit;
-        return "prepaid card not valid for agent ". $self->agentnum;
-      }
-      $self->agentnum($prepay_credit->agentnum);
-    }
-    my $error = $prepay_credit->delete;
+    $prepay_identifier = $self->payinfo;
+    $self->payinfo('');
+
+    my $error = $self->get_prepay($prepay_identifier, \$amount, \$seconds);
     if ( $error ) {
       $dbh->rollback if $oldAutoCommit;
-      return "removing prepay_credit (transaction rolled back): $error";
+      #return "error applying prepaid card (transaction rolled back): $error";
+      return $error;
     }
+
   }
 
   my $error = $self->SUPER::insert;
@@ -407,15 +395,8 @@ sub insert {
     return "No svc_acct record to apply pre-paid time";
   }
 
-  if ( $prepay_credit && $prepay_credit->amount ) {
-    my $cust_pay = new FS::cust_pay {
-      'custnum' => $self->custnum,
-      'paid'    => $prepay_credit->amount,
-      #'_date'   => #date the prepaid card was purchased???
-      'payby'   => 'PREP',
-      'payinfo' => $prepay_credit->identifier,
-    };
-    $error = $cust_pay->insert;
+  if ( $amount ) {
+    $error = $self->insert_prepay($amount, $prepay_identifier);
     if ( $error ) {
       $dbh->rollback if $oldAutoCommit;
       return "inserting prepayment (transaction rolled back): $error";
@@ -526,6 +507,195 @@ sub order_pkgs {
   ''; #no error
 }
 
+=item recharge_prepay IDENTIFIER | PREPAY_CREDIT_OBJ [ , AMOUNTREF, SECONDSREF ]
+
+Recharges this (existing) customer with the specified prepaid card (see
+L<FS::prepay_credit>), specified either by I<identifier> or as an
+FS::prepay_credit object.  If there is an error, returns the error, otherwise
+returns false.
+
+Optionally, two scalar references can be passed as well.  They will have their
+values filled in with the amount and number of seconds applied by this prepaid
+card.
+
+=cut
+
+sub recharge_prepay { 
+  my( $self, $prepay_credit, $amountref, $secondsref ) = @_;
+
+  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;
+
+  my( $amount, $seconds ) = ( 0, 0 );
+
+  my $error = $self->get_prepay($prepay_credit, \$amount, \$seconds)
+           || $self->increment_seconds($seconds)
+           || $self->insert_cust_pay_prepay( $amount,
+                                             ref($prepay_credit)
+                                               ? $prepay_credit->identifier
+                                               : $prepay_credit
+                                           );
+
+  if ( $error ) {
+    $dbh->rollback if $oldAutoCommit;
+    return $error;
+  }
+
+  if ( defined($amountref)  ) { $$amountref  = $amount;  }
+  if ( defined($secondsref) ) { $$secondsref = $seconds; }
+
+  $dbh->commit or die $dbh->errstr if $oldAutoCommit;
+  '';
+
+}
+
+=item get_prepay IDENTIFIER | PREPAY_CREDIT_OBJ , AMOUNTREF, SECONDSREF
+
+Looks up and deletes a prepaid card (see L<FS::prepay_credit>),
+specified either by I<identifier> or as an FS::prepay_credit object.
+
+References to I<amount> and I<seconds> scalars should be passed as arguments
+and will be incremented by the values of the prepaid card.
+
+If the prepaid card specifies an I<agentnum> (see L<FS::agent>), it is used to
+check or set this customer's I<agentnum>.
+
+If there is an error, returns the error, otherwise returns false.
+
+=cut
+
+
+sub get_prepay {
+  my( $self, $prepay_credit, $amountref, $secondsref ) = @_;
+
+  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;
+
+  unless ( ref($prepay_credit) ) {
+
+    my $identifier = $prepay_credit;
+
+    $prepay_credit = qsearchs(
+      'prepay_credit',
+      { 'identifier' => $prepay_credit },
+      '',
+      'FOR UPDATE'
+    );
+
+    unless ( $prepay_credit ) {
+      $dbh->rollback if $oldAutoCommit;
+      return "Invalid prepaid card: ". $identifier;
+    }
+
+  }
+
+  if ( $prepay_credit->agentnum ) {
+    if ( $self->agentnum && $self->agentnum != $prepay_credit->agentnum ) {
+      $dbh->rollback if $oldAutoCommit;
+      return "prepaid card not valid for agent ". $self->agentnum;
+    }
+    $self->agentnum($prepay_credit->agentnum);
+  }
+
+  my $error = $prepay_credit->delete;
+  if ( $error ) {
+    $dbh->rollback if $oldAutoCommit;
+    return "removing prepay_credit (transaction rolled back): $error";
+  }
+
+  $$amountref  += $prepay_credit->amount;
+  $$secondsref += $prepay_credit->seconds;
+
+  $dbh->commit or die $dbh->errstr if $oldAutoCommit;
+  '';
+
+}
+
+=item increment_seconds SECONDS
+
+Updates this customer's single or primary account (see L<FS::svc_acct>) by
+the specified number of seconds.  If there is an error, returns the error,
+otherwise returns false.
+
+=cut
+
+sub increment_seconds {
+  my( $self, $seconds ) = @_;
+  warn "$me increment_seconds called: $seconds seconds\n"
+    if $DEBUG;
+
+  my @cust_pkg = grep { $_->part_pkg->svcpart('svc_acct') }
+                      $self->ncancelled_pkgs;
+
+  if ( ! @cust_pkg ) {
+    return 'No packages with primary or single services found'.
+           ' to apply pre-paid time';
+  } elsif ( scalar(@cust_pkg) > 1 ) {
+    #maybe have a way to specify the package/account?
+    return 'Multiple packages found to apply pre-paid time';
+  }
+
+  my $cust_pkg = $cust_pkg[0];
+  warn "  found package pkgnum ". $cust_pkg->pkgnum. "\n"
+    if $DEBUG;
+
+  my @cust_svc =
+    $cust_pkg->cust_svc( $cust_pkg->part_pkg->svcpart('svc_acct') );
+
+  if ( ! @cust_svc ) {
+    return 'No account found to apply pre-paid time';
+  } elsif ( scalar(@cust_svc) > 1 ) {
+    return 'Multiple accounts found to apply pre-paid time';
+  }
+  
+  my $svc_acct = $cust_svc[0]->svc_x;
+  warn "  found service svcnum ". $svc_acct->pkgnum.
+       ' ('. $svc_acct->email. ")\n"
+    if $DEBUG;
+
+  $svc_acct->increment_seconds($seconds);
+
+}
+
+=item insert_cust_pay_prepay AMOUNT [ PAYINFO ]
+
+Inserts a prepayment in the specified amount for this customer.  An optional
+second argument can specify the prepayment identifier for tracking purposes.
+If there is an error, returns the error, otherwise returns false.
+
+=cut
+
+sub insert_cust_pay_prepay {
+  my( $self, $amount ) = splice(@_, 0, 2);
+  my $payinfo = scalar(@_) ? shift : '';
+
+  my $cust_pay = new FS::cust_pay {
+    'custnum' => $self->custnum,
+    'paid'    => $amount,
+    #'_date'   => #date the prepaid card was purchased???
+    'payby'   => 'PREP',
+    'payinfo' => $payinfo,
+  };
+  $cust_pay->insert;
+
+}
+
 =item reexport
 
 This method is deprecated.  See the I<depend_jobnum> option to the insert and
index a045193..4963120 100644 (file)
@@ -37,7 +37,6 @@ use FS::svc_www;
 @ISA = qw( FS::svc_Common );
 
 $DEBUG = 0;
-#$DEBUG = 1;
 $me = '[FS::svc_acct]';
 
 #ask FS::UID to run this stuff for us later
@@ -1117,12 +1116,45 @@ sub acct_snarf {
 
 =item decrement_seconds SECONDS
 
-Decrements the I<seconds> field of this record by the given amount.
+Decrements the I<seconds> field of this record by the given amount.  If there
+is an error, returns the error, otherwise returns false.
 
 =cut
 
 sub decrement_seconds {
-  my( $self, $seconds ) = @_;
+  shift->_op_seconds('-', @_);
+}
+
+=item increment_seconds SECONDS
+
+Increments the I<seconds> field of this record by the given amount.  If there
+is an error, returns the error, otherwise returns false.
+
+=cut
+
+sub increment_seconds {
+  shift->_op_seconds('+', @_);
+}
+
+
+my %op2action = (
+  '-' => 'suspend',
+  '+' => 'unsuspend',
+);
+my %op2condition = (
+  '-' => sub { my($self, $seconds) = @_;
+               $self->seconds - $seconds <= 0;
+             },
+  '+' => sub { my($self, $seconds) = @_;
+               $self->seconds + $seconds > 0;
+             },
+);
+
+sub _op_seconds {
+  my( $self, $op, $seconds ) = @_;
+  warn "$me _op_seconds called for svcnum ". $self->svcnum.
+       ' ('. $self->email. "): $op $seconds\n"
+    if $DEBUG;
 
   local $SIG{HUP} = 'IGNORE';
   local $SIG{INT} = 'IGNORE';
@@ -1134,22 +1166,41 @@ sub decrement_seconds {
   my $oldAutoCommit = $FS::UID::AutoCommit;
   local $FS::UID::AutoCommit = 0;
   my $dbh = dbh;
-  
-  my $sth = dbh->prepare(
-    'UPDATE svc_acct SET seconds = seconds - ? WHERE svcnum = ?'
-  ) or die dbh->errstr;;
-  $sth->execute($seconds, $self->svcnum) or die $sth->errstr;
-  if ( $conf->exists('svc_acct-usage_suspend')
-       && $self->seconds - $seconds <= 0       ) {
-    #my $error = $self->suspend;
-    my $error = $self->cust_svc->cust_pkg->suspend;
-    die $error if $error;
+
+  my $sql = "UPDATE svc_acct SET seconds = ".
+            " CASE WHEN seconds IS NULL THEN 0 ELSE seconds END ". #$seconds||0
+            " $op ? WHERE svcnum = ?";
+  warn "$me $sql\n"
+    if $DEBUG;
+
+  my $sth = $dbh->prepare( $sql )
+    or die "Error preparing $sql: ". $dbh->errstr;
+  my $rv = $sth->execute($seconds, $self->svcnum);
+  die "Error executing $sql: ". $sth->errstr
+    unless defined($rv);
+  die "Can't update seconds for svcnum". $self->svcnum
+    if $rv == 0;
+
+  my $action = $op2action{$op};
+
+  if ( $conf->exists("svc_acct-usage_$action")
+       && &{$op2condition{$op}}($self, $seconds)    ) {
+    #my $error = $self->$action();
+    my $error = $self->cust_svc->cust_pkg->$action();
+    if ( $error ) {
+      $dbh->rollback if $oldAutoCommit;
+      return "Error ${action}ing: $error";
+    }
   }
 
+  warn "$me update sucessful; committing\n"
+    if $DEBUG;
   $dbh->commit or die $dbh->errstr if $oldAutoCommit;
+  '';
 
 }
 
+
 =item seconds_since TIMESTAMP
 
 Returns the number of seconds this account has been online since TIMESTAMP,
index 0f58175..1e6c4ec 100644 (file)
@@ -31,6 +31,7 @@ $socket .= '.'.$tag if defined $tag && length($tag);
   'cancel'               => 'MyAccount/cancel',        #add to ss cgi!
   'payment_info'         => 'MyAccount/payment_info',
   'process_payment'      => 'MyAccount/process_payment',
+  'process_prepay'       => 'MyAccount/process_prepay',
   'list_pkgs'            => 'MyAccount/list_pkgs',     #add to ss cgi!
   'order_pkg'            => 'MyAccount/order_pkg',     #add to ss cgi!
   'cancel_pkg'           => 'MyAccount/cancel_pkg',    #add to ss cgi!
index e8be07e..7a2b750 100644 (file)
@@ -1,7 +1,6 @@
 <HTML><HEAD><TITLE>MyAccount</TITLE></HEAD>
 <BODY BGCOLOR="#eeeeee"><FONT SIZE=5>MyAccount</FONT><BR><BR>
 <%= $url = "$selfurl?session=$session_id;action="; ''; %>
-<TABLE BORDER=0 CELLPADDING=4><TR>
 <%= include('myaccount_menu') %>
 <TD VALIGN="top">
 <%= $small_custview %>
index 16054a7..8468deb 100644 (file)
@@ -1,7 +1,6 @@
 <HTML><HEAD><TITLE>MyAccount</TITLE></HEAD>
 <BODY BGCOLOR="#eeeeee"><FONT SIZE=5>MyAccount</FONT><BR><BR>
 <%= $url = "$selfurl?session=$session_id;action="; ''; %>
-<TABLE BORDER=0 CELLPADDING=4><TR>
 <%= include('myaccount_menu') %>
 <TD VALIGN="top">
 
index 3522c08..1bbbe90 100644 (file)
@@ -1,7 +1,6 @@
 <HTML><HEAD><TITLE>MyAccount</TITLE></HEAD>
 <BODY BGCOLOR="#eeeeee"><FONT SIZE=5>MyAccount</FONT><BR><BR>
 <%= $url = "$selfurl?session=$session_id;action="; ''; %>
-<TABLE BORDER=0 CELLPADDING=4><TR>
 <%= include('myaccount_menu') %>
 <TD VALIGN="top">
 <FONT SIZE=4>Make a payment</FONT><BR><BR>
index 9997d70..546ca11 100644 (file)
@@ -1,7 +1,6 @@
 <HTML><HEAD><TITLE>MyAccount</TITLE></HEAD>
 <BODY BGCOLOR="#eeeeee"><FONT SIZE=5>MyAccount</FONT><BR><BR>
 <%= $url = "$selfurl?session=$session_id;action="; ''; %>
-<TABLE BORDER=0 CELLPADDING=4><TR>
 <%= include('myaccount_menu') %>
 <TD VALIGN="top">
 
index ba3b3f2..f2e5e99 100644 (file)
@@ -1,13 +1,89 @@
 <%= $url = "$selfurl?session=$session_id;action="; ''; %>
+<TABLE BORDER=0><TR>
 <TD VALIGN="top" HEIGHT=384 BGCOLOR="#dddddd">
 
-<A HREF="<%= $url %>myaccount">Overview</A><BR><BR>
-<!--A HREF="<%= $url %>change_bill"-->Change&nbsp;payment&nbsp;info</A>&nbsp;*<BR><BR>
-<!--A HREF="<%= $url %>change_ship"-->Change&nbsp;service&nbsp;address</A>&nbsp;*<BR><BR>
-<A HREF="<%= $url %>provision">Setup&nbsp;my&nbsp;services</A><BR><BR>
-<!--A HREF="<%= $url %>order"-->Purchase&nbsp;additional&nbsp;package</A>&nbsp;*<BR><BR>
-<!--<A HREF="<%= $url %>pw_list">Change&nbsp;password(s)</A>&nbsp;*<BR><BR>-->
-<A HREF="passwd.html">Change&nbsp;password(s)</A><BR><BR>
-<A HREF="<%= $url %>logout">Logout</A><BR><BR>
+<TABLE CELLSPACING=0 BORDER=0>
+
+<%= 
+
+my @menu = (
+{ title=>' ' },
+{ title=>'Overview', url=>'myaccount', size=>'+1', },
+{ title=>' ' },
+
+{ title=>'Purchase', size=>'+1', },
+  { title=>'Purchase additional package*', url=>'order', 'indent'=>2 },
+);
+
+if ( 1 ) { #XXXFIXME "enable selfservice prepay features" flag or something, eventually per-pkg or something really fancy
+
+  push @menu, (
+    { title=>'Recharge my account with a credit card',
+      url=>'make_payment', indent=>2 },
+    { title=>'Recharge my account with a prepaid card',
+      url=>'recharge_prepay', indent=>2 },
+  );
+
+}
+
+push @menu, (
+
+{ title=>' ' },
+
+{ title=>'Setup my services', url=>'provision', size=>'+1', },
+
+{ title=>' ' },
+
+{ title=>'Change my information', size=>'+1', },
+  { title=>'Change payment information*', url=>'change_bill', indent=>2 },
+  { title=>'Change service address*',     url=>'change_ship', indent=>2 },
+  { title=>'Change password(s)*',         url=>'hmmmFIXME',   indent=>2 },
+
+{ title=>' ' },
+
+{ title=>'Logout',   url=>'logout', size=>'+1', },
+
+);
+
+foreach my $item ( @menu ) {
+
+  $OUT .= '<TR><TD'; 
+  if ( exists $item->{'url'} && $action eq $item->{'url'} ) {
+    $OUT .= ' BGCOLOR="#eeeeee" '.
+            ' STYLE="border-top: 1px solid black;'.
+                   ' border-left: 1px solid black;'.
+                   ' border-bottom: 1px solid black"';
+  } else {
+    $OUT .= ' STYLE="border-right: 1px solid black"';
+  }
+  $OUT.='>';
+
+  $OUT .= '<FONT SIZE="'. $item->{'size'}. '">'
+    if exists $item->{'size'};
+
+  $OUT .= '&nbsp;' x $item->{'indent'}
+    if exists $item->{'indent'};
+
+  $OUT .= '<A HREF="'. $url. $item->{'url'}. '">'
+    if exists $item->{'url'} && $action ne $item->{'url'};
+
+  $item->{'title'} =~ s/ /&nbsp;/g;
+  $OUT .= $item->{'title'};
+
+  $OUT .= '</FONT>'
+    if exists $item->{'size'};
+
+  $OUT .= '</A>'
+    if exists $item->{'url'} && $action ne $item->{'url'};
+
+  $OUT .= '</TD></TR>';
+
+}
+
+%>
+
+</TABLE>
+
+<A HREF="passwd.html">(tempFIXME) Change&nbsp;password(s)</A><BR><BR>
 *&nbsp;coming&nbsp;soon
 </TD>
index 44289de..de6c54d 100644 (file)
@@ -1,7 +1,6 @@
 <HTML><HEAD><TITLE>MyAccount</TITLE></HEAD>
 <BODY BGCOLOR="#eeeeee"><FONT SIZE=5>MyAccount</FONT><BR><BR>
 <%= $url = "$selfurl?session=$session_id;action="; ''; %>
-<TABLE BORDER=0 CELLPADDING=4><TR>
 <%= include('myaccount_menu') %>
 <TD VALIGN="top">
 <FONT SIZE=4>Payment results</FONT><BR><BR>
index 7052059..200a80d 100644 (file)
@@ -1,7 +1,6 @@
 <HTML><HEAD><TITLE>MyAccount</TITLE></HEAD>
 <BODY BGCOLOR="#eeeeee"><FONT SIZE=5>MyAccount</FONT><BR><BR>
 <%= $url = "$selfurl?session=$session_id;action="; ''; %>
-<TABLE BORDER=0 CELLPADDING=4><TR>
 <%= include('myaccount_menu') %>
 <TD VALIGN="top">
 
index 772cf08..2328fa1 100644 (file)
@@ -1,7 +1,6 @@
 <HTML><HEAD><TITLE><%= $error ? 'MyAccount' : sprintf("Your serial number is %010d-$title", $id) %></TITLE></HEAD>
 <BODY BGCOLOR="#eeeeee"><FONT SIZE=5>MyAccount</FONT><BR><BR>
 <%= $url = "$selfurl?session=$session_id;action="; ''; %>
-<TABLE BORDER=0 CELLPADDING=4><TR>
 <%= include('myaccount_menu') %>
 <TD VALIGN="top">
 
index 6d80e89..d31e607 100644 (file)
@@ -1,7 +1,6 @@
 <HTML><HEAD><TITLE>MyAccount</TITLE></HEAD>
 <BODY BGCOLOR="#eeeeee"><FONT SIZE=5>MyAccount</FONT><BR><BR>
 <%= $url = "$selfurl?session=$session_id;action="; ''; %>
-<TABLE BORDER=0 CELLPADDING=4><TR>
 <%= include('myaccount_menu') %>
 <TD VALIGN="top">
 <%= include('provision_list') %>
index cf35857..5054074 100644 (file)
@@ -1,7 +1,6 @@
 <HTML><HEAD><TITLE>MyAccount</TITLE></HEAD>
 <BODY BGCOLOR="#eeeeee"><FONT SIZE=5>MyAccount</FONT><BR><BR>
 <%= $url = "$selfurl?session=$session_id;action="; ''; %>
-<TABLE BORDER=0 CELLPADDING=4><TR>
 <%= include('myaccount_menu') %>
 <TD VALIGN="top">
 <%= include('svc_acct') %>
diff --git a/fs_selfservice/FS-SelfService/cgi/recharge_prepay.html b/fs_selfservice/FS-SelfService/cgi/recharge_prepay.html
new file mode 100644 (file)
index 0000000..f858459
--- /dev/null
@@ -0,0 +1,36 @@
+<HTML><HEAD><TITLE>MyAccount</TITLE></HEAD>
+<BODY BGCOLOR="#eeeeee"><FONT SIZE=5>MyAccount</FONT><BR><BR>
+<%= $url = "$selfurl?session=$session_id;action="; ''; %>
+<%= include('myaccount_menu') %>
+<TD VALIGN="top">
+<FONT SIZE=4>Recharge with prepaid card</FONT><BR><BR>
+<FORM NAME="OneTrueForm" METHOD="POST" ACTION="<%=$selfurl%>" onSubmit="document.OneTrueForm.process.disabled=true">
+<INPUT TYPE="hidden" NAME="session" VALUE="<%=$session_id%>">
+<INPUT TYPE="hidden" NAME="action" VALUE="recharge_results">
+<TABLE BGCOLOR="#cccccc">
+<!--
+<TR>
+  <TD ALIGN="right">Amount&nbsp;Due</TD>
+  <TD>
+    <TABLE><TR><TD BGCOLOR="#ffffff">
+      $<%=sprintf("%.2f",$balance)%>
+    </TD></TR></TABLE>
+  </TD>
+</TR>
+-->
+<TR>
+  <TD ALIGN="right">Prepaid&nbsp;card&nbsp;number</TD>
+  <TD>
+    <INPUT TYPE="text" NAME="prepaid_cardnum" SIZE=20 MAXLENGTH=19 VALUE="<%=$prepaid_cardnum%>">
+  </TD>
+</TR>
+</TABLE>
+<BR>
+<INPUT TYPE="hidden" NAME="paybatch" VALUE="<%=$paybatch%>">
+<INPUT TYPE="submit" NAME="process" VALUE="Recharge"> <!-- onClick="this.disabled=true"> -->
+</FORM>
+</TD></TR></TABLE>
+<HR>
+<FONT SIZE="-2">powered by <a href="http://www.sisd.com/freeside">freeside</a></FONT>
+</BODY></HTML>
+
diff --git a/fs_selfservice/FS-SelfService/cgi/recharge_results.html b/fs_selfservice/FS-SelfService/cgi/recharge_results.html
new file mode 100644 (file)
index 0000000..ec3ea2c
--- /dev/null
@@ -0,0 +1,24 @@
+<HTML><HEAD><TITLE>MyAccount</TITLE></HEAD>
+<BODY BGCOLOR="#eeeeee"><FONT SIZE=5>MyAccount</FONT><BR><BR>
+<%= $url = "$selfurl?session=$session_id;action="; ''; %>
+<%= include('myaccount_menu') %>
+<TD VALIGN="top">
+<FONT SIZE=4>Recharge results</FONT><BR><BR>
+<%= if ( $error ) {
+  $OUT .= qq!<FONT SIZE="+1" COLOR="#ff0000">Error processing your prepaid card: $error</FONT>!;
+} else {
+  $OUT .= 'Prepaid card recharge sucessful!<BR><BR>';
+
+  $OUT .= '$'. sprintf('%.2f', $amount). ' added to your account.<BR><BR>'
+    if $amount;
+
+  $OUT .= $duration. ' added to your account.<BR><BR>'
+    if $seconds;
+
+  $OUT .= 'Thank you.';
+} %>
+</TD></TR></TABLE>
+<HR>
+<FONT SIZE="-2">powered by <a href="http://www.sisd.com/freeside">freeside</a></FONT>
+</BODY></HTML>
+
index 0816758..034a684 100644 (file)
@@ -9,6 +9,7 @@ use Text::Template;
 use HTML::Entities;
 use FS::SelfService qw( login customer_info invoice
                         payment_info process_payment 
+                        process_prepay
                         list_pkgs
                         part_svc_info provision_acct provision_external
                         unprovision_svc
@@ -61,7 +62,7 @@ $session_id = $cgi->param('session');
 
 #order|pw_list XXX ???
 $cgi->param('action') =~
-    /^(myaccount|view_invoice|make_payment|payment_results|logout|change_bill|change_ship|provision|provision_svc|process_svc_acct|process_svc_external|delete_svc)$/
+    /^(myaccount|view_invoice|make_payment|payment_results|recharge_prepay|recharge_results|logout|change_bill|change_ship|provision|provision_svc|process_svc_acct|process_svc_external|delete_svc)$/
   or die "unknown action ". $cgi->param('action');
 my $action = $1;
 
@@ -79,6 +80,7 @@ if ( $result->{error} eq "Can't resume session" ) { #ick
 warn "processing template $action\n";
 do_template($action, {
   'session_id' => $session_id,
+  'action'     => $action, #so the menu knows what tab we're on...
   %{$result}
 });
 
@@ -173,6 +175,22 @@ sub payment_results {
 
 }
 
+sub recharge_prepay {
+  customer_info( 'session_id' => $session_id );
+}
+
+sub recharge_results {
+
+  my $prepaid_cardnum = $cgi->param('prepaid_cardnum');
+  $prepaid_cardnum =~ s/\W//g;
+  $prepaid_cardnum =~ /^(\w*)$/ or die "illegal prepaid card number";
+  $prepaid_cardnum = $1;
+
+  process_prepay ( 'session_id'     => $session_id,
+                   'prepaid_cardnum' => $prepaid_cardnum,
+                 );
+}
+
 sub logout {
   FS::SelfService::logout( 'session_id' => $session_id );
 }
index 46f7318..72d0619 100644 (file)
@@ -1,7 +1,6 @@
 <HTML><HEAD><TITLE>MyAccount</TITLE></HEAD>
 <BODY BGCOLOR="#eeeeee"><FONT SIZE=5>MyAccount</FONT><BR><BR>
 <%= $url = "$selfurl?session=$session_id;action="; ''; %>
-<TABLE BORDER=0 CELLPADDING=4><TR>
 <%= include('myaccount_menu') %>
 <TD VALIGN="top">
 
index 246a7fb..1486d7b 100755 (executable)
@@ -283,6 +283,11 @@ foreach $attribute ( grep /^rc_/, $svc_acct->fields ) {
 print '<TR><TD ALIGN="right">RADIUS groups</TD><TD BGCOLOR="#ffffff">'.
       join('<BR>', $svc_acct->radius_groups). '</TD></TR>';
 
+if ( $svc_acct->seconds =~ /^\d+$/ ) {
+  print '<TR><TD ALIGN="right">Prepaid time</TD><TD BGCOLOR="#ffffff">'.
+        duration_exact($svc_acct->seconds). '</TD></TR>';
+}
+
 # Can this be abstracted further?  Maybe a library function like
 # widget('HTML', 'view', $svc_acct) ?  It would definitely make UI 
 # style management easier.