summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--FS/FS/ClientAPI/MyAccount.pm37
-rw-r--r--FS/FS/Conf.pm7
-rw-r--r--FS/FS/cust_main.pm236
-rw-r--r--FS/FS/svc_acct.pm77
-rw-r--r--fs_selfservice/FS-SelfService/SelfService.pm1
-rw-r--r--fs_selfservice/FS-SelfService/cgi/agent_delete_svc.html1
-rw-r--r--fs_selfservice/FS-SelfService/cgi/delete_svc.html1
-rw-r--r--fs_selfservice/FS-SelfService/cgi/make_payment.html1
-rw-r--r--fs_selfservice/FS-SelfService/cgi/myaccount.html1
-rw-r--r--fs_selfservice/FS-SelfService/cgi/myaccount_menu.html92
-rw-r--r--fs_selfservice/FS-SelfService/cgi/payment_results.html1
-rw-r--r--fs_selfservice/FS-SelfService/cgi/process_svc_acct.html1
-rw-r--r--fs_selfservice/FS-SelfService/cgi/process_svc_external.html1
-rw-r--r--fs_selfservice/FS-SelfService/cgi/provision.html1
-rw-r--r--fs_selfservice/FS-SelfService/cgi/provision_svc_acct.html1
-rw-r--r--fs_selfservice/FS-SelfService/cgi/recharge_prepay.html36
-rw-r--r--fs_selfservice/FS-SelfService/cgi/recharge_results.html24
-rw-r--r--fs_selfservice/FS-SelfService/cgi/selfservice.cgi20
-rw-r--r--fs_selfservice/FS-SelfService/cgi/view_invoice.html1
-rwxr-xr-xhttemplate/view/svc_acct.cgi5
20 files changed, 479 insertions, 66 deletions
diff --git a/FS/FS/ClientAPI/MyAccount.pm b/FS/FS/ClientAPI/MyAccount.pm
index 478973396..60d1f64d9 100644
--- a/FS/FS/ClientAPI/MyAccount.pm
+++ b/FS/FS/ClientAPI/MyAccount.pm
@@ -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'})
diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm
index ea2785bdf..a1fdd034e 100644
--- a/FS/FS/Conf.pm
+++ b/FS/FS/Conf.pm
@@ -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;
diff --git a/FS/FS/cust_main.pm b/FS/FS/cust_main.pm
index 1edd319cb..775523a56 100644
--- a/FS/FS/cust_main.pm
+++ b/FS/FS/cust_main.pm
@@ -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
diff --git a/FS/FS/svc_acct.pm b/FS/FS/svc_acct.pm
index a0451938a..496312062 100644
--- a/FS/FS/svc_acct.pm
+++ b/FS/FS/svc_acct.pm
@@ -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,
diff --git a/fs_selfservice/FS-SelfService/SelfService.pm b/fs_selfservice/FS-SelfService/SelfService.pm
index 0f581758b..1e6c4ec0c 100644
--- a/fs_selfservice/FS-SelfService/SelfService.pm
+++ b/fs_selfservice/FS-SelfService/SelfService.pm
@@ -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!
diff --git a/fs_selfservice/FS-SelfService/cgi/agent_delete_svc.html b/fs_selfservice/FS-SelfService/cgi/agent_delete_svc.html
index e8be07ed1..7a2b75071 100644
--- a/fs_selfservice/FS-SelfService/cgi/agent_delete_svc.html
+++ b/fs_selfservice/FS-SelfService/cgi/agent_delete_svc.html
@@ -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 %>
diff --git a/fs_selfservice/FS-SelfService/cgi/delete_svc.html b/fs_selfservice/FS-SelfService/cgi/delete_svc.html
index 16054a77c..8468deb4b 100644
--- a/fs_selfservice/FS-SelfService/cgi/delete_svc.html
+++ b/fs_selfservice/FS-SelfService/cgi/delete_svc.html
@@ -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">
diff --git a/fs_selfservice/FS-SelfService/cgi/make_payment.html b/fs_selfservice/FS-SelfService/cgi/make_payment.html
index 3522c0867..1bbbe90b2 100644
--- a/fs_selfservice/FS-SelfService/cgi/make_payment.html
+++ b/fs_selfservice/FS-SelfService/cgi/make_payment.html
@@ -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>
diff --git a/fs_selfservice/FS-SelfService/cgi/myaccount.html b/fs_selfservice/FS-SelfService/cgi/myaccount.html
index 9997d7059..546ca1112 100644
--- a/fs_selfservice/FS-SelfService/cgi/myaccount.html
+++ b/fs_selfservice/FS-SelfService/cgi/myaccount.html
@@ -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">
diff --git a/fs_selfservice/FS-SelfService/cgi/myaccount_menu.html b/fs_selfservice/FS-SelfService/cgi/myaccount_menu.html
index ba3b3f2ff..f2e5e998e 100644
--- a/fs_selfservice/FS-SelfService/cgi/myaccount_menu.html
+++ b/fs_selfservice/FS-SelfService/cgi/myaccount_menu.html
@@ -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>
diff --git a/fs_selfservice/FS-SelfService/cgi/payment_results.html b/fs_selfservice/FS-SelfService/cgi/payment_results.html
index 44289deba..de6c54dae 100644
--- a/fs_selfservice/FS-SelfService/cgi/payment_results.html
+++ b/fs_selfservice/FS-SelfService/cgi/payment_results.html
@@ -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>
diff --git a/fs_selfservice/FS-SelfService/cgi/process_svc_acct.html b/fs_selfservice/FS-SelfService/cgi/process_svc_acct.html
index 7052059c4..200a80dc9 100644
--- a/fs_selfservice/FS-SelfService/cgi/process_svc_acct.html
+++ b/fs_selfservice/FS-SelfService/cgi/process_svc_acct.html
@@ -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">
diff --git a/fs_selfservice/FS-SelfService/cgi/process_svc_external.html b/fs_selfservice/FS-SelfService/cgi/process_svc_external.html
index 772cf0838..2328fa10f 100644
--- a/fs_selfservice/FS-SelfService/cgi/process_svc_external.html
+++ b/fs_selfservice/FS-SelfService/cgi/process_svc_external.html
@@ -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">
diff --git a/fs_selfservice/FS-SelfService/cgi/provision.html b/fs_selfservice/FS-SelfService/cgi/provision.html
index 6d80e89db..d31e6070b 100644
--- a/fs_selfservice/FS-SelfService/cgi/provision.html
+++ b/fs_selfservice/FS-SelfService/cgi/provision.html
@@ -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') %>
diff --git a/fs_selfservice/FS-SelfService/cgi/provision_svc_acct.html b/fs_selfservice/FS-SelfService/cgi/provision_svc_acct.html
index cf3585721..50540742a 100644
--- a/fs_selfservice/FS-SelfService/cgi/provision_svc_acct.html
+++ b/fs_selfservice/FS-SelfService/cgi/provision_svc_acct.html
@@ -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
index 000000000..f8584597a
--- /dev/null
+++ b/fs_selfservice/FS-SelfService/cgi/recharge_prepay.html
@@ -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
index 000000000..ec3ea2c7a
--- /dev/null
+++ b/fs_selfservice/FS-SelfService/cgi/recharge_results.html
@@ -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>
+
diff --git a/fs_selfservice/FS-SelfService/cgi/selfservice.cgi b/fs_selfservice/FS-SelfService/cgi/selfservice.cgi
index 0816758fb..034a684c6 100644
--- a/fs_selfservice/FS-SelfService/cgi/selfservice.cgi
+++ b/fs_selfservice/FS-SelfService/cgi/selfservice.cgi
@@ -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 );
}
diff --git a/fs_selfservice/FS-SelfService/cgi/view_invoice.html b/fs_selfservice/FS-SelfService/cgi/view_invoice.html
index 46f731890..72d061980 100644
--- a/fs_selfservice/FS-SelfService/cgi/view_invoice.html
+++ b/fs_selfservice/FS-SelfService/cgi/view_invoice.html
@@ -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">
diff --git a/httemplate/view/svc_acct.cgi b/httemplate/view/svc_acct.cgi
index 246a7fbc8..1486d7b11 100755
--- a/httemplate/view/svc_acct.cgi
+++ b/httemplate/view/svc_acct.cgi
@@ -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.