diff options
-rw-r--r-- | FS/FS/ClientAPI/MyAccount.pm | 23 | ||||
-rw-r--r-- | FS/FS/Conf.pm | 7 | ||||
-rw-r--r-- | fs_selfservice/FS-SelfService/cgi/change_pay.html | 8 | ||||
-rw-r--r-- | fs_selfservice/FS-SelfService/cgi/check.html | 103 | ||||
-rw-r--r-- | fs_selfservice/FS-SelfService/cgi/make_ach_payment.html | 28 | ||||
-rw-r--r-- | ng_selfservice/elements/check.php | 94 | ||||
-rw-r--r-- | ng_selfservice/payment_accounts.php | 78 | ||||
-rw-r--r-- | ng_selfservice/payment_ach.php | 10 |
8 files changed, 276 insertions, 75 deletions
diff --git a/FS/FS/ClientAPI/MyAccount.pm b/FS/FS/ClientAPI/MyAccount.pm index 505111e1a..5c86b7820 100644 --- a/FS/FS/ClientAPI/MyAccount.pm +++ b/FS/FS/ClientAPI/MyAccount.pm @@ -742,6 +742,11 @@ sub edit_info { my $cust_main = qsearchs('cust_main', { 'custnum' => $custnum } ) or return { 'error' => "unknown custnum $custnum" }; + my $conf = new FS::Conf; + if (($p->{payby} eq "CHEK" || $p->{payby} eq "DCHEK") && $conf->exists('selfservice-ACH_info_readonly')) { + return { 'error' => "You do not have authority to add a bank account" }; + } + my $new = new FS::cust_main { $cust_main->hash }; $new->set( $_ => $p->{$_} ) @@ -769,8 +774,6 @@ sub edit_info { # but if it hasn't been passed in at all, leave ship_location alone-- # DON'T change it to match bill_location. - my $conf = new FS::Conf; - my @invoicing_list; if ( exists $p->{'invoicing_list'} || exists $p->{'postal_invoicing'} ) { #false laziness with httemplate/edit/process/cust_main.cgi @@ -840,6 +843,7 @@ sub payment_info { 'show_paystate' => $conf->exists('show_bankstate'), 'save_unchecked' => $conf->exists('selfservice-save_unchecked'), + 'ach_read_only' => $conf->exists('selfservice-ACH_info_readonly'), }; @@ -986,12 +990,18 @@ sub validate_payment { my $payinfo2 = $1; $payinfo = $payinfo1. '@'. $payinfo2; + my $achonfile = 0; foreach my $cust_payby ($cust_main->cust_payby('CHEK','DCHK')) { if ( $cust_payby->paymask eq $payinfo ) { $payinfo = $cust_payby->payinfo; + $achonfile = 1; last; } } + + if ($conf->exists('selfservice-ACH_info_readonly') && !$achonfile) { + return { 'error' => "You are not allowed to change your payment information." }; + } } elsif ( $payby eq 'CARD' || $payby eq 'DCRD' ) { @@ -1738,8 +1748,13 @@ sub delete_payby { }) or return { 'error' => 'unknown custpaybynum '. $p->{'custpaybynum'} }; - return { 'error' => $cust_payby->delete }; - + my $conf = new FS::Conf; + if (($cust_payby->payby eq "DCHK" || $cust_payby->payby eq "CHEK") && $conf->exists('selfservice-ACH_info_readonly')) { + return { 'error' => "Sorry you do not have permission to delete bank information." }; + } + else { + return { 'error' => $cust_payby->delete }; + } } sub cancel { diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm index 5ab9a3ff6..b5b5ec89e 100644 --- a/FS/FS/Conf.pm +++ b/FS/FS/Conf.pm @@ -5823,6 +5823,13 @@ and customer address. Include units.', }, { + 'key' => 'selfservice-ACH_info_readonly', + 'section' => 'self-service', + 'description' => 'make ACH on self service portal read only', + 'type' => 'checkbox', + }, + + { 'key' => 'selfservice-announcement', 'section' => 'self-service', 'description' => 'HTML announcement to display to all authenticated users on account overview page', diff --git a/fs_selfservice/FS-SelfService/cgi/change_pay.html b/fs_selfservice/FS-SelfService/cgi/change_pay.html index 6898dc7f8..e38ba762d 100644 --- a/fs_selfservice/FS-SelfService/cgi/change_pay.html +++ b/fs_selfservice/FS-SelfService/cgi/change_pay.html @@ -37,6 +37,11 @@ 'PREP' => qq/Prepaid Card/, 'PREPAY' => qq/Prepaid Card/, ); + + ## Don't show CHEK or DCHK option if ACH is read only + delete( $payby_index{'CHEK'} ) unless !$ach_read_only; + delete( $payby_index{'DCHK'} ) unless !$ach_read_only; + tie my %options, 'Tie::IxHash', (); foreach my $payby_option ( grep { exists( $payby_index{$_} ) } @paybys ) { $options{$payby_option} = $payby_index{$payby_option}; @@ -55,6 +60,9 @@ delete $options{'DCRD'} unless $payby eq 'DCRD' || ! exists $options{'CARD'}; delete $options{'DCHK'} unless $payby eq 'DCHK' || ! exists $options{'CHEK'}; + ## setting payby to default to layer if only one. should we always display first layer? + if (keys %options == 1) { @p = keys %options; $payby = $p[0]; } + HTML::Widgets::SelectLayers->new( options => \%options, selected_layer => $payby, diff --git a/fs_selfservice/FS-SelfService/cgi/check.html b/fs_selfservice/FS-SelfService/cgi/check.html index 68753fe08..17635c306 100644 --- a/fs_selfservice/FS-SelfService/cgi/check.html +++ b/fs_selfservice/FS-SelfService/cgi/check.html @@ -1,54 +1,97 @@ <TR> <TD ALIGN="right">Account type</TD> - <TD> - <SELECT NAME="paytype"> - <%= foreach ( @paytypes ) { - $selected = $paytype eq $_ ? ' SELECTED' : ''; - $OUT .= qq(<OPTION$selected VALUE="$_">$_\n); - } %> - </SELECT> + <TD <%= ($ach_read_only ? ' BGCOLOR="#ffffff"' : '') %> > + <%= + if ($ach_read_only) { + $OUT = $paytype . '<INPUT TYPE="hidden" NAME="paytype" VALUE="' . $paytype . '">'; + } else { + $OUT .= '<SELECT NAME="paytype">'; + foreach ( @paytypes ) { + $selected = $paytype eq $_ ? ' SELECTED' : ''; + $OUT .= qq(<OPTION$selected VALUE="$_">$_\n); + } + $OUT .= '</SELECT>'; + } + %> </TD> -</TD><TR> +</TR><TR> <TD ALIGN="right">Account number</TD> - <TD><INPUT TYPE="text" NAME="payinfo1" SIZE=10 MAXLENGTH=20 VALUE="<%=$payinfo1%>"></TD> -</TD><TR> + <TD <%= ($ach_read_only ? ' BGCOLOR="#ffffff"' : '') %> > + <%= if ($ach_read_only) { + $OUT = qq! $payinfo1 <INPUT TYPE="hidden" NAME="payinfo1" VALUE="$payinfo1"> !; + } else { + $OUT = qq! <INPUT TYPE="text" NAME="payinfo1" SIZE=10 MAXLENGTH=20 VALUE="$payinfo1"> !; + } + %> + </TD> +</TR><TR> <TD ALIGN="right">ABA/Routing number</TD> - <TD><INPUT TYPE="text" NAME="payinfo2" SIZE=10 MAXLENGTH=9 VALUE="<%=$payinfo2%>"></TD> + <TD <%= ($ach_read_only ? ' BGCOLOR="#ffffff"' : '') %> > + <%= + if ($ach_read_only) { + $OUT = qq! $payinfo2 <INPUT TYPE="hidden" NAME="payinfo2" VALUE="$payinfo2"> !; + } else { + $OUT = qq! <INPUT TYPE="text" NAME="payinfo2" SIZE=10 MAXLENGTH=20 VALUE="$payinfo2"> !; + } + %> + </TD> </TR><TR> <TD ALIGN="right">Bank name</TD> - <TD><INPUT TYPE="text" SIZE=32 MAXLENGTH=80 NAME="payname" VALUE="<%=$payname%>"></TD> -</TR><TR> + <TD <%= ($ach_read_only ? ' BGCOLOR="#ffffff"' : '') %> > + <%= + if ($ach_read_only) { + $OUT = qq! $payname <INPUT TYPE="hidden" NAME="payname" VALUE="$payname"> !; + } else { + $OUT = qq! <INPUT TYPE="text" NAME="payname" SIZE=10 MAXLENGTH=20 VALUE="$payname"> !; + } + %> + </TD> +</TR> <%= $OUT = ''; if ($show_paystate) { - $OUT .= qq!<TD ALIGN="right">Bank state</TD><TD><SELECT NAME="paystate">!; - for ( @states ) { - $OUT .= '<OPTION'. ($_ eq $paystate ? ' SELECTED' : '' ). ">$_\n"; + $OUT .= '<TR><TD ALIGN="right">Bank state</TD><TD' . ($ach_read_only ? ' BGCOLOR="#ffffff"' : '') . '>'; + if ($ach_read_only) { + $OUT .= qq! $paystate <INPUT TYPE="hidden" NAME="paystate" VALUE="$paystate"> !; + } else { + $OUT .= '<SELECT NAME="paystate">'; + for ( @states ) { + $OUT .= '<OPTION'. ($_ eq $paystate ? ' SELECTED' : '' ). ">$_\n"; + } + $OUT .= '</SELECT>'; } - $OUT .= '</SELECT></TD></TR><TR>'; + $OUT .= '</TD></TR>'; } %> <%= $OUT = ''; if ($show_ss) { - $OUT .= '<TD ALIGN="right">Account holder<BR>Social '; - $OUT .= 'security or tax ID #</TD><TD>'; - $OUT .= qq!<INPUT TYPE="text" SIZE=32 MAXLENGTH=80 NAME="ss" VALUE="$ss">!; - $OUT .= '</TD></TR><TR>'; + $OUT .= '<TR><TD ALIGN="right">Account holder<BR>Social '; + $OUT .= 'security or tax ID #</TD><TD' . ($ach_read_only ? ' BGCOLOR="#ffffff"' : '') . '>'; + if ($ach_read_only) { + $OUT .= qq! $ss <INPUT TYPE="hidden" NAME="ss" VALUE="$ss">!; + } else { + $OUT .= qq!<INPUT TYPE="text" SIZE=32 MAXLENGTH=80 NAME="ss" VALUE="$ss">!; + } + $OUT .= '</TD></TR>'; } %> <%= $OUT = ''; if ($show_stateid) { - $OUT .= '<TD ALIGN="right">'; - $OUT .= qq!Account holder<BR>$stateid_label</TD><TD>!; - $OUT .= qq!<INPUT TYPE="text" SIZE=32 MAXLENGTH=80 NAME="stateid" VALUE="$stateid"></TD>!; - $OUT .= qq!<TD ALIGN="right">$stateid_state_label</TD>!; - $OUT .= '<TD><SELECT NAME="stateid_state">'; - for ( @states ) { - $OUT .= '<OPTION'. ($_ eq $stateid_state ? ' SELECTED' : '' ). ">$_\n"; + $OUT .= qq!<TR><TD ALIGN="right">Account holder<BR>$stateid_label</TD>!; + $OUT .= '<TD' . ($ach_read_only ? ' BGCOLOR="#ffffff"' : '') . '>'; + if ($ach_read_only) { + $OUT .= qq! $stateid <INPUT TYPE="hidden" NAME="stateid" VALUE="$stateid">!; + } else { + $OUT .= qq!<INPUT TYPE="text" SIZE=32 MAXLENGTH=80 NAME="stateid" VALUE="$stateid"></TD>!; + $OUT .= qq!<TD ALIGN="right">$stateid_state_label</TD>!; + $OUT .= '<TD><SELECT NAME="stateid_state">'; + for ( @states ) { + $OUT .= '<OPTION'. ($_ eq $stateid_state ? ' SELECTED' : '' ). ">$_\n"; + } + $OUT .='</SELECT>'; } - $OUT .='</SELECT></TD></TR><TR>'; + $OUT .='</TD></TR>'; } %> -</TR> diff --git a/fs_selfservice/FS-SelfService/cgi/make_ach_payment.html b/fs_selfservice/FS-SelfService/cgi/make_ach_payment.html index 8c2dfe305..1183b2ba0 100644 --- a/fs_selfservice/FS-SelfService/cgi/make_ach_payment.html +++ b/fs_selfservice/FS-SelfService/cgi/make_ach_payment.html @@ -20,24 +20,28 @@ EOF <TR> <TD ALIGN="right">Payment amount</TD> <TD> - <TABLE><TR><TD BGCOLOR="#ffffff"> + <TABLE><TR><TD> <%= $money_char %><INPUT TYPE="text" NAME="amount" SIZE=8 VALUE="<%= ($balance > 0) ? $balance : '' %>"> </TD></TR></TABLE> </TD> </TR> <%= include('discount_term') %> <%= include('check') %> -<TR> - <TD COLSPAN=2> - <INPUT TYPE="checkbox" <%= $save_unchecked ? '' : 'CHECKED' %> NAME="save" VALUE="1"> - Remember this information - </TD> -</TR><TR> - <TD COLSPAN=2> - <INPUT TYPE="checkbox"<%= $payby eq 'CHEK' ? ' CHECKED' : '' %> NAME="auto" VALUE="1" onClick="if (this.checked) { document.OneTrueForm.save.checked=true; }"> - Charge future payments to this account automatically - </TD> -</TR> + +<%= + $OUT = ''; + if ($ach_read_only) { + if ($payby eq 'CHEK') { + $OUT .= '<TR><TD COLSPAN=2><INPUT TYPE="hidden" NAME="auto" VALUE="1"></TD></TR>'; + } + } else { + $OUT .= '<TR><TD COLSPAN=2><INPUT TYPE="checkbox"' . ($save_unchecked ? '' : 'CHECKED ') . 'NAME="save" VALUE="1">'; + $OUT .= 'Remember this information</TD></TR>'; + $OUT .= '<TR><TD COLSPAN=2><INPUT TYPE="checkbox"' . ($payby eq 'CHEK' ? ' CHECKED' : '') . 'NAME="auto" VALUE="1" onClick="if (this.checked) { document.OneTrueForm.save.checked=true; }">'; + $OUT .= 'Charge future payments to this account automatically</TD></TR>'; + } +%> + </TABLE> <BR> <INPUT TYPE="hidden" NAME="paybatch" VALUE="<%=$paybatch%>"> diff --git a/ng_selfservice/elements/check.php b/ng_selfservice/elements/check.php index b026c92e4..fd0cd6d91 100644 --- a/ng_selfservice/elements/check.php +++ b/ng_selfservice/elements/check.php @@ -1,50 +1,88 @@ +<? if ($ach_read_only) { $bgShade = 'BGCOLOR="#ffffff"'; } ?> <TR> <TD ALIGN="right">Account type</TD> - <TD> - <SELECT NAME="paytype"> + <TD <? echo $bgShade; ?>> + <? if ($ach_read_only) { echo htmlspecialchars($paytype); ?> + <INPUT TYPE="hidden" NAME="paytype" VALUE="<? echo $paytype; ?>"> + <? } else { ?> + <SELECT NAME="paytype"> <? foreach ( $paytypes AS $pt ) { ?> <OPTION <? if ($pt == $paytype ) { echo 'SELECTED'; } ?> VALUE="<? echo $pt; ?>"><? echo $pt; ?> <? } ?> - </SELECT> + </SELECT> + <? } ?> </TD> </TR><TR> <TD ALIGN="right">Account number</TD> - <TD><INPUT TYPE="text" NAME="payinfo1" SIZE=10 MAXLENGTH=20 VALUE="<? echo $payinfo1; ?>"></TD> -</TD><TR> + <TD <? echo $bgShade; ?>> + <? if ($ach_read_only) { echo htmlspecialchars($payinfo1); ?> + <INPUT TYPE="hidden" NAME="payinfo1" VALUE="<? echo $payinfo1; ?>"> + <? } else { ?> + <INPUT TYPE="text" NAME="payinfo1" SIZE=10 MAXLENGTH=20 VALUE="<? echo $payinfo1; ?>"> + <? } ?> + </TD> +</TR><TR> <TD ALIGN="right">ABA/Routing number</TD> - <TD><INPUT TYPE="text" NAME="payinfo2" SIZE=10 MAXLENGTH=9 VALUE="<? echo $payinfo2; ?>"></TD> + <TD <? echo $bgShade; ?>> + <? if ($ach_read_only) { echo htmlspecialchars($payinfo2); ?> + <INPUT TYPE="hidden" NAME="payinfo2" VALUE="<? echo $payinfo2; ?>"> + <? } else { ?> + <INPUT TYPE="text" NAME="payinfo2" SIZE=10 MAXLENGTH=9 VALUE="<? echo $payinfo2; ?>"></TD> + <? } ?> </TR><TR> <TD ALIGN="right">Bank name</TD> - <TD><INPUT TYPE="text" SIZE=32 MAXLENGTH=80 NAME="payname" VALUE="<? echo $payname; ?>"></TD> + <TD <? echo $bgShade; ?>> + <? if ($ach_read_only) { echo htmlspecialchars($payname); ?> + <INPUT TYPE="hidden" NAME="payname" VALUE="<? echo $payname; ?>"></TD> + <? } else { ?> + <INPUT TYPE="text" SIZE=32 MAXLENGTH=80 NAME="payname" VALUE="<? echo $payname; ?>"></TD> + <? } ?> </TR><TR> <? if ($show_paystate) { ?> - <TD ALIGN="right">Bank state</TD> - <TD> - <SELECT NAME="paystate"> - <? foreach ( $states AS $s ) { ?> - <OPTION <? if ($s == $paystate ) { echo 'SELECTED'; } ?>><? echo $s; ?> - <? } ?> - </SELECT> - </TD> - </TR><TR> + <TR> + <TD ALIGN="right">Bank state</TD> + <TD <? echo $bgShade; ?>> + <? if ($ach_read_only) { echo htmlspecialchars($paystate); ?> + <INPUT TYPE="hidden" NAME="paystate" VALUE="<? echo $paystate; ?>"></TD> + <? } else { ?> + <SELECT NAME="paystate"> + <? foreach ( $states AS $s ) { ?> + <OPTION <? if ($s == $paystate ) { echo 'SELECTED'; } ?>><? echo $s; ?> + <? } ?> + </SELECT></TD> + <? } ?> + </TR> <? } ?> <? if ($show_ss) { ?> - <TD ALIGN="right">Account holder<BR>Social security or tax ID #</TD><TD> - <INPUT TYPE="text" SIZE=32 MAXLENGTH=80 NAME="ss" VALUE="<? echo $ss; ?>"> - </TD></TR><TR> + <TR> + <TD ALIGN="right">Account holder<BR>Social security or tax ID #</TD> + <TD <? echo $bgShade; ?>> + <? if ($ach_read_only) { echo htmlspecialchars($ss); ?> + <INPUT TYPE="hidden" NAME="ss" VALUE="<? echo $ss; ?>"></TD> + <? } else { ?> + <INPUT TYPE="text" SIZE=32 MAXLENGTH=80 NAME="ss" VALUE="<? echo $ss; ?>"></TD> + <? } ?> + </TR> <? } ?> <? if ($show_stateid) { ?> - <TD ALIGN="right"> - Account holder<BR><? echo $stateid_label; ?></TD><TD> - <INPUT TYPE="text" SIZE=32 MAXLENGTH=80 NAME="stateid" VALUE="<? echo $stateid; ?>"></TD> - <TD ALIGN="right"><? echo $stateid_state_label; ?></TD> - <TD><SELECT NAME="stateid_state"> - <? foreach ( $states AS $s ) { ?> - <OPTION <? if ($s == $stateid_state ) { echo 'SELECTED'; } ?>><? echo $s; ?> + <TR> + <TD ALIGN="right">Account holder<BR><? echo $stateid_label; ?></TD> + <TD <? echo $bgShade; ?>> + <? if ($ach_read_only) { echo htmlspecialchars($stateid); ?> + <INPUT TYPE="hidden" NAME="stateid" VALUE="<? echo $stateid; ?>"></TD> + <TD <? echo $bgShade; ?>> <? echo $stateid_state; ?> + <INPUT TYPE="hidden" NAME="stateid_state" VALUE="<? echo $stateid_state; ?>"></TD> + <? } else { ?> + <INPUT TYPE="text" SIZE=32 MAXLENGTH=80 NAME="stateid" VALUE="<? echo $stateid; ?>"></TD> + <TD ALIGN="right"><? echo $stateid_state_label; ?></TD> + <TD><SELECT NAME="stateid_state"> + <? foreach ( $states AS $s ) { ?> + <OPTION <? if ($s == $stateid_state ) { echo 'SELECTED'; } ?>><? echo $s; ?> + <? } ?> + </SELECT></TD> <? } ?> - </SELECT></TD></TR><TR> + </TR> <? } ?> -</TR> diff --git a/ng_selfservice/payment_accounts.php b/ng_selfservice/payment_accounts.php new file mode 100644 index 000000000..e70142a0a --- /dev/null +++ b/ng_selfservice/payment_accounts.php @@ -0,0 +1,78 @@ +<? $title ='Payment Accounts'; include('elements/header.php'); ?> +<? $current_menu = 'payment_accounts.php'; include('elements/menu.php'); ?> +<H1>My Payment Accounts</H1> +<br> + +<? +if ( isset($_GET['action']) && $_GET['action'] ) { + $action = $_GET['action']; +} + +if ($action == 'deleteaccount') { + + if ( isset($_GET['paybynum']) && $_GET['paybynum'] ) { + if ( preg_match( '/^(\d+)$/', $_GET['paybynum'] ) ) { + $paybynum = $_GET['paybynum']; + $error = $freeside->delete_payby( array( + 'session_id' => $_COOKIE['session_id'], + 'custpaybynum' => $paybynum, + ) ); + } + else { + $error['error'] = 'Bad Payby Number'; + } + } + + if ( isset($error['error']) && $error['error'] ) { + $error = $error['error']; + } + else { + $error = "Account " . $paybynum . " Deleted"; + } + +?> + <FONT COLOR="red"><? echo $error ?></FONT> + <P> +<? +} + + $payment_info = $freeside->list_payby( array( + 'session_id' => $_COOKIE['session_id'], + ) ); + + if ( isset($payment_info['error']) && $payment_info['error'] ) { + $error = $payment_info['error']; + header('Location:index.php?error='. urlencode($error)); + die(); + } + + extract($payment_info); +?> + +<TABLE> + <TR> + <TD> </TD> + <TD>Type</TD> + <TD>Account Type</TD> + <TD>Account Mask</TD> + <TD>Bank Name</TD> + </TR> + +<? + foreach ($payby as $payaccount) { +?> + <TR> + <TD><A HREF="payment_accounts.php?action=deleteaccount&paybynum=<? echo $payaccount['custpaybynum'] ?>">delete</A></TD> + <TD><? echo $payaccount['payby'] ?></TD> + <TD><? echo $payaccount['paytype'] ?></TD> + <TD><? echo $payaccount['paymask'] ?></TD> + <TD><? echo htmlspecialchars($payaccount['payname']) ?></TD> + </TR> + <? + } + ?> + +</TABLE> + +<? include('elements/menu_footer.php'); ?> +<? include('elements/footer.php'); ?> diff --git a/ng_selfservice/payment_ach.php b/ng_selfservice/payment_ach.php index ecbd9c749..a3dce76c4 100644 --- a/ng_selfservice/payment_ach.php +++ b/ng_selfservice/payment_ach.php @@ -54,7 +54,7 @@ if ( $receipt_html ) { ?> $error = $payment_error; - ?> +?> <? include('elements/error.php'); ?> @@ -82,6 +82,12 @@ if ( $receipt_html ) { ?> <? include('elements/check.php') ?> + <? if ($ach_read_only) { ?> + <? if ( $payby == 'CARD' ) { ?> + <INPUT TYPE="hidden" NAME="auto" VALUE="1"> + <? } ?> + </TD></TR> + <? } else { ?> <TR> <TD COLSPAN=2> <INPUT TYPE="checkbox" <? if ( ! $save_unchecked ) { echo 'CHECKED'; } ?> NAME="save" VALUE="1"> @@ -93,6 +99,8 @@ if ( $receipt_html ) { ?> Charge future payments to this account automatically </TD> </TR> + <? } ?> + </TABLE> <BR> <INPUT TYPE="hidden" NAME="paybatch" VALUE="<? echo $paybatch; ?>"> |