diff options
Diffstat (limited to 'httemplate/edit/cust_main')
-rw-r--r-- | httemplate/edit/cust_main/billing.html | 504 | ||||
-rw-r--r-- | httemplate/edit/cust_main/birthdate.html | 16 | ||||
-rw-r--r-- | httemplate/edit/cust_main/bottomfixup.html | 19 | ||||
-rw-r--r-- | httemplate/edit/cust_main/bottomfixup.js | 399 | ||||
-rw-r--r-- | httemplate/edit/cust_main/choose_tax_location.html | 87 | ||||
-rw-r--r-- | httemplate/edit/cust_main/contact.html | 150 | ||||
-rw-r--r-- | httemplate/edit/cust_main/first_pkg.html | 55 | ||||
-rw-r--r-- | httemplate/edit/cust_main/first_pkg/select-part_pkg.html | 170 | ||||
-rw-r--r-- | httemplate/edit/cust_main/first_pkg/svc_acct.html | 88 | ||||
-rw-r--r-- | httemplate/edit/cust_main/first_pkg/svc_phone.html | 82 | ||||
-rw-r--r-- | httemplate/edit/cust_main/top_misc.html | 117 |
11 files changed, 1687 insertions, 0 deletions
diff --git a/httemplate/edit/cust_main/billing.html b/httemplate/edit/cust_main/billing.html new file mode 100644 index 000000000..aeb67b662 --- /dev/null +++ b/httemplate/edit/cust_main/billing.html @@ -0,0 +1,504 @@ +%if ( $payby_default eq 'HIDE' ) { +% +% $cust_main->payby('BILL') unless $cust_main->payby; +% my $payby = $cust_main->payby; + + <INPUT TYPE="hidden" NAME="payby" VALUE="<% $payby %>"> + + <INPUT TYPE="hidden" NAME="<%$payby%>_payinfo" VALUE="<% $cust_main->paymask %>"> + +% foreach my $field (qw( payname paycvv paystart_month paystart_year payissue payip paytype paystate )) { + + <INPUT TYPE="hidden" NAME="<% $payby.'_'.$field %>" VALUE="<% $cust_main->get($field) %>"> + +% } + +% #false laziness w/elements/select-month_year.html & view/cust_main/billing.html +% my( $mon, $year ); +% my $date = $cust_main->paydate || '12-2037'; +% if ( $date =~ /^(\d{4})-(\d{1,2})-\d{1,2}$/ ) { #PostgreSQL date format +% ( $mon, $year ) = ( $2, $1 ); +% } elsif ( $date =~ /^(\d{1,2})-(\d{1,2}-)?(\d{4}$)/ ) { +% ( $mon, $year ) = ( $1, $3 ); +% } else { +% die "unrecognized expiration date format: $date"; +% } + + <INPUT TYPE="hidden" NAME="<%$payby%>_exp_month" VALUE="<% $mon %>"> + <INPUT TYPE="hidden" NAME="<%$payby%>_exp_year" VALUE="<% $year %>"> + + <INPUT TYPE="hidden" NAME="tax" VALUE="<% $cust_main->tax %>"> + + <INPUT TYPE="hidden" NAME="invoicing_list" VALUE="<% join(', ', @invoicing_list) %>"> + +% } else { +% +% my $r = qq!<font color="#ff0000">*</font> !; + + <BR><FONT SIZE="+1"><B>Billing information</B></FONT> + <% &ntable("#cccccc") %> + + <TR> + <TD ALIGN="right" WIDTH="200"><%$r%>Billing type</TD> + + <SCRIPT> + + var mywindow = -1; + function myopen(filename,windowname,properties) { + myclose(); + mywindow = window.open(filename,windowname,properties); + } + function myclose() { + if ( mywindow != -1 ) + mywindow.close(); + mywindow = -1; + } + + var achwindow = -1; + function achopen(filename,windowname,properties) { + achclose(); + achwindow = window.open(filename,windowname,properties); + } + function achclose() { + if ( achwindow != -1 ) + achwindow.close(); + achwindow = -1; + } + + function card_changed(what) { + if ( + what.form.payinfo.value.substring(0, 4) == '4093' + || what.form.payinfo.value.substring(0, 4) == '4911' + || what.form.payinfo.value.substring(0, 4) == '4936' + || what.form.payinfo.value.substring(0, 6) == '564132' + || what.form.payinfo.value.substring(0, 2) == '63' + || what.form.payinfo.value.substring(0, 2) == '67' + ) + { + what.form.paystart_month.disabled = false; + what.form.paystart_year.disabled = false; + what.form.payissue.disabled = false; + what.form.paystart_month.style.backgroundColor = '#ffffff'; + what.form.paystart_year.style.backgroundColor = '#ffffff'; + what.form.payissue.style.backgroundColor = '#ffffff'; + document.getElementById('paystart_label').style.color = '#000000'; + document.getElementById('payissue_label').style.color = '#000000'; + } else { + what.form.paystart_month.disabled = true; + what.form.paystart_year.disabled = true; + what.form.payissue.disabled = true; + what.form.paystart_month.style.backgroundColor = '#dddddd'; + what.form.paystart_year.style.backgroundColor = '#dddddd'; + what.form.payissue.style.backgroundColor = '#dddddd'; + document.getElementById('paystart_label').style.color = '#999999'; + document.getElementById('payissue_label').style.color = '#999999'; + } + return true; + } + + </SCRIPT> + + <% include('/elements/init_overlib.html') %> + +% my $payby = $cust_main->payby; +% my $paytype = $cust_main->paytype; +% my( $account, $aba ) = split('@', $payinfo); +% +% my $disabled = 'DISABLED style="background-color: #dddddd"'; +% my $text_disabled = 'style="color: #999999"'; +% +% if ( $payby =~ /^(CARD|DCRD)$/ && cardtype($payinfo) =~ /^(Switch|Solo)$/ ) { +% $disabled = 'style="background-color: #ffffff"'; +% $text_disabled = 'style="color: #000000";' +% } +% +% my %payby = ( +% +% 'CARD' => +% +% '<TABLE BGCOLOR="#cccccc" BORDER=0 CELLSPACING=0 HEIGHT=192>'. +% +% qq!<TR><TD ALIGN="right" WIDTH="200">${r}Card number </TD>!. +% qq!<TD WIDTH="408"><INPUT TYPE="text" NAME="CARD_payinfo" VALUE="!. ( $payby =~ /^(CARD|DCRD)$/ ? $payinfo : '' ). qq!" MAXLENGTH=19 onChange="card_changed(this)" onKeyUp="card_changed(this)"></TD></TR>!. +% +% qq!<TR><TD ALIGN="right" WIDTH="200">${r}Expiration </TD>!. +% '<TD WIDTH="408">'. +% +% include('/elements/select-month_year.html', +% 'prefix' => 'CARD_exp', +% 'selected_date' => +% ( $payby =~ /^(CARD|DCRD)$/ ? $cust_main->paydate : '' ), +% ). +% +% '</TD></TR>'. +% +% qq!<TR><TD ALIGN="right" WIDTH="200">CVV2 !. +% +% qq!(<A HREF="javascript:void(0);" onClick="overlib( OLiframeContent('../docs/cvv2.html', 480, 352, 'cvv2_popup' ), CAPTION, 'CVV2 Help', STICKY, AUTOSTATUSCAP, CLOSECLICK, DRAGGABLE ); return false;">help</A>)!. +% qq!</TD>!. +% '<TD WIDTH="408"><INPUT TYPE="text" NAME="CARD_paycvv" VALUE="'. ( $payby =~ /^(CARD|DCRD)$/ && !$cust_main->is_encrypted($cust_main->paycvv) ? $cust_main->paycvv : '' ). '" SIZE=4 MAXLENGTH=4>'. +% +% +% qq!<TR><TD ALIGN="right" WIDTH="200"><SPAN ID="paystart_label" $text_disabled>Start date </SPAN></TD>!. +% '<TD WIDTH="408">'. +% +% include('/elements/select-month_year.html', +% 'prefix' => 'CARD_paystart', +% 'disabled' => $disabled, +% 'empty_option' => 1, +% 'start_year' => 2000, +% 'end_year' => (localtime())[5] + 1900, +% 'selected_date' => ( +% ( $payby =~ /^(CARD|DCRD)$/ +% && cardtype($payinfo) =~ /^(Switch|Solo)$/ ) +% ? $cust_main->paystart_month. '-'. +% $cust_main->paystart_year +% : '' +% ) +% ). +% +% qq!<SPAN ID="payissue_label" $text_disabled> or Issue number </SPAN>!. +% '<INPUT TYPE="text" NAME="CARD_payissue" VALUE="'. ( $payby =~ /^(CARD|DCRD)$/ ? $cust_main->payissue : '' ). qq!" SIZE=3 MAXLENGTH=2 $disabled></TD></TR>!. +% +% qq!<TR><TD ALIGN="right" WIDTH="200">${r}Exact name on card </TD>!. +% qq!<TD WIDTH="408"><INPUT TYPE="text" NAME="CARD_payname" VALUE="!. ( $payby =~ /^(CARD|DCRD)$/ ? $cust_main->payname : '' ). qq!"></TD></TR>!. +% +% qq!<TR><TD COLSPAN=2 WIDTH="608"><INPUT TYPE="checkbox" NAME="CARD_payauto" !. ( $payby eq 'DCRD' ? '' : 'CHECKED' ). '> Charge future payments to this card automatically</TD></TR>'. +% +% '</TABLE>', +% +% 'CHEK' => +% +% '<TABLE BGCOLOR="#cccccc" BORDER=0 CELLSPACING=0 HEIGHT=192>'. +% +% qq!<TR><TD ALIGN="right" WIDTH="200">${r}Account number </TD>!. +% qq!<TD><INPUT TYPE="text" SIZE=12 NAME="CHEK_payinfo1" VALUE="!. ( $payby =~ /^(CHEK|DCHK)$/ ? $account : '' ). '"></TD>'. +% qq!<TD ALIGN="right">Type</TD><TD><SELECT NAME="CHEK_paytype">!. +% join('', map { qq!<OPTION VALUE="$_" !.($paytype eq $_ ? 'SELECTED' : '').">$_</OPTION>" } @FS::cust_main::paytypes). +% qq!</SELECT></TD></TR>!. +% +% qq!<TR><TD ALIGN="right" WIDTH="200">${r}ABA/Routing number </TD>!. +% qq!<TD COLSPAN="3" WIDTH="408"><INPUT TYPE="text" SIZE=10 MAXLENGTH=9 NAME="CHEK_payinfo2" VALUE="!. ( $payby =~ /^(CHEK|DCHK)$/ ? $aba : '' ). qq!" SIZE=10 MAXLENGTH=9> !. +% qq!(<A HREF="javascript:void(0);" onClick="overlib( OLiframeContent('../docs/ach.html', 380, 240, 'ach_popup' ), CAPTION, 'ACH Help', STICKY, AUTOSTATUSCAP, CLOSECLICK, DRAGGABLE ); return false;">help</A>)!. +% qq!</TD></TR>!. +% +% qq!<INPUT TYPE="hidden" NAME="CHEK_exp_month" VALUE="12">!. +% qq!<INPUT TYPE="hidden" NAME="CHEK_exp_year" VALUE="2037">!. +% +% qq!<TR><TD ALIGN="right" WIDTH="200">${r}Bank name </TD>!. +% qq!<TD COLSPAN="3" WIDTH="408"><INPUT TYPE="text" NAME="CHEK_payname" VALUE="!. ( $payby =~ /^(CHEK|DCHK)$/ ? $cust_main->payname : '' ). qq!"></TD></TR>!. +% ( $conf->exists('show_bankstate') ? +% qq!<TR><TD ALIGN="right" WIDTH="200">$paystate_label</TD>!. +% qq!<TD COLSPAN="3" WIDTH="408">!. +% include('/elements/select-state.html', +% 'empty' => '(choose)', +% 'state' => $cust_main->paystate, +% 'country' => $cust_main->country, +% 'prefix' => 'CHEK_pay', +% ). "</TD></TR>" +% : '<INPUT TYPE="hidden" NAME="CHEK_paystate" VALUE="'. +% $cust_main->paystate. '">' +% ). +% +% +% qq!<TR><TD COLSPAN=4 WIDTH="608"><INPUT TYPE="checkbox" NAME="CHEK_payauto" !. ( $payby eq 'DCHK' ? '' : 'CHECKED' ). '> Charge future payments to this electronic check automatically</TD></TR>'. +% +% '<TR><TD> </TD></TR>'. +% '<TR><TD> </TD></TR>'. +% '<TR><TD> </TD></TR>'. +% +% '</TABLE>', +% +% 'LECB' => +% +% '<TABLE BGCOLOR="#cccccc" BORDER=0 CELLSPACING=0 HEIGHT=192>'. +% +% qq!<TR><TD ALIGN="right" WIDTH="200">${r}Phone number </TD>!. +% qq!<TD WIDTH="408"><INPUT TYPE="text" NAME="LECB_payinfo" VALUE="!. ( $payby eq 'LECB' ? $cust_main->payinfo : '' ). qq!" MAXLENGTH=15 SIZE=16></TD></TR>!. +% +% qq!<INPUT TYPE="hidden" NAME="LECB_exp_month" VALUE="12">!. +% qq!<INPUT TYPE="hidden" NAME="LECB_exp_year" VALUE="2037">!. +% qq!<INPUT TYPE="hidden" NAME="LECB_payname" VALUE="">!. +% +% '<TR><TD> </TD></TR>'. +% '<TR><TD> </TD></TR>'. +% '<TR><TD> </TD></TR>'. +% '<TR><TD> </TD></TR>'. +% '<TR><TD> </TD></TR>'. +% '<TR><TD> </TD></TR>'. +% +% '</TABLE>', +% +% 'BILL' => +% +% '<TABLE BGCOLOR="#cccccc" BORDER=0 CELLSPACING=0 HEIGHT=192>'. +% +% qq!<TR><TD ALIGN="right" WIDTH="200">P.O. </TD>!. +% qq!<TD WIDTH="408"><INPUT TYPE="text" NAME="BILL_payinfo" VALUE="!. ( $payby eq 'BILL' ? $cust_main->payinfo : '' ). qq!"></TD></TR>!. +% +% qq!<INPUT TYPE="hidden" NAME="BILL_exp_month" VALUE="12">!. +% qq!<INPUT TYPE="hidden" NAME="BILL_exp_year" VALUE="2037">!. +% +% qq!<TR><TD ALIGN="right" WIDTH="200">Attention </TD>!. +% qq!<TD WIDTH="408"><INPUT TYPE="text" NAME="BILL_payname" VALUE="!. ( $payby eq 'BILL' ? $cust_main->payname : '' ). qq!"></TD></TR>!. +% +% '<TR><TD> </TD></TR>'. +% '<TR><TD> </TD></TR>'. +% '<TR><TD> </TD></TR>'. +% '<TR><TD> </TD></TR>'. +% '<TR><TD> </TD></TR>'. +% +% '</TABLE>', +% +% 'COMP' => +% +% '<TABLE BGCOLOR="#cccccc" BORDER=0 CELLSPACING=0 HEIGHT=192>'. +% +% qq!<TR><TD ALIGN="right" WIDTH="200">${r}Approved by </TD>!. +% qq!<TD WIDTH="408"><INPUT TYPE="text" NAME="COMP_payinfo" VALUE=""></TD></TR>!. +% +% qq!<TR><TD ALIGN="right" WIDTH="200">${r}Expiration </TD>!. +% '<TD WIDTH="408">'. +% +% include('/elements/select-month_year.html', +% 'prefix' => 'COMP_exp', +% 'selected_date' => +% ( $payby eq 'COMP' ? $cust_main->paydate : '' ), +% ). +% +% '</TD></TR>'. +% +% '<TR><TD> </TD></TR>'. +% '<TR><TD> </TD></TR>'. +% '<TR><TD> </TD></TR>'. +% '<TR><TD> </TD></TR>'. +% '<TR><TD> </TD></TR>'. +% +% '</TABLE>', +% +% 'CASH' => +% +% '<TABLE BGCOLOR="#cccccc" BORDER=0 CELLSPACING=0 HEIGHT=192>'. +% +% qq!<TR><TD ALIGN="right" WIDTH="200">${r}Amount </TD>!. +% qq!<TD WIDTH="408"><INPUT TYPE="text" NAME="CASH_paid" VALUE="!. ( $payby eq 'CASH' ? $cust_main->paid : '' ). qq!"></TD></TR>!. +% +% '<TR><TD> </TD></TR>'. +% '<TR><TD> </TD></TR>'. +% '<TR><TD> </TD></TR>'. +% '<TR><TD> </TD></TR>'. +% '<TR><TD> </TD></TR>'. +% '<TR><TD> </TD></TR>'. +% +% '</TABLE>', +% +% 'WEST' => +% +% '<TABLE BGCOLOR="#cccccc" BORDER=0 CELLSPACING=0 HEIGHT=192>'. +% +% qq!<TR><TD ALIGN="right" WIDTH="200">${r}Amount </TD>!. +% qq!<TD WIDTH="408"><INPUT TYPE="text" NAME="WEST_paid" VALUE="!. ( $payby eq 'WEST' ? $cust_main->paid : '' ). qq!"></TD></TR>!. +% +% '<TR><TD> </TD></TR>'. +% '<TR><TD> </TD></TR>'. +% '<TR><TD> </TD></TR>'. +% '<TR><TD> </TD></TR>'. +% '<TR><TD> </TD></TR>'. +% '<TR><TD> </TD></TR>'. +% +% '</TABLE>', +% +% 'MCRD' => +% +% '<TABLE BGCOLOR="#cccccc" BORDER=0 CELLSPACING=0 HEIGHT=192>'. +% +% qq!<TR><TD ALIGN="right" WIDTH="200">${r}Amount </TD>!. +% qq!<TD WIDTH="408"><INPUT TYPE="text" NAME="MCRD_paid" VALUE="!. ( $payby eq 'MCRD' ? $cust_main->paid : '' ). qq!"></TD></TR>!. +% +% '<TR><TD> </TD></TR>'. +% '<TR><TD> </TD></TR>'. +% '<TR><TD> </TD></TR>'. +% '<TR><TD> </TD></TR>'. +% '<TR><TD> </TD></TR>'. +% '<TR><TD> </TD></TR>'. +% +% '</TABLE>', +% +% ); +% +% #this should use FS::payby +% my @allopt = qw( CARD CHEK LECB BILL CASH WEST MCRD COMP ); +% +% my %allopt = map { $_ => FS::payby->shortname($_) } @allopt; +% +% if ( $cust_main->custnum ) { +% #don't offer CASH/WEST/MCRD initial payment types when editing customer +% delete $allopt{$_} for qw(CASH WEST MCRD); +% } +% +% my @options = grep exists( $allopt{$_} ), @payby; +% +% my %payby2option = ( +% ( map { $_ => $_ } @options ), +% 'DCRD' => 'CARD', +% 'DCHK' => 'CHEK', +% ); + + <TD WIDTH="408"> + <% include( '/elements/selectlayers.html', + 'field' => 'payby', + 'curr_value' => $payby2option{$payby || $payby_default || $payby[0] }, + 'options' => \@options, + 'labels' => \%allopt, + 'html_between' => '</TD></TR></TABLE>', + 'layer_callback' => sub { my $layer = shift; $payby{$layer}; }, + ) + %> + + <% &ntable("#cccccc") %> + + <TR><TD> </TD></TR> + +% my @exempt_groups = grep /\S/, $conf->config('tax-cust_exempt-groups'); + + <TR> + <TD WIDTH="608" COLSPAN="2"><INPUT TYPE="checkbox" NAME="tax" VALUE="Y" <% $cust_main->tax eq "Y" ? 'CHECKED' : '' %>> Tax Exempt<% @exempt_groups ? ' (all taxes)' : '' %></TD> + </TR> + +% foreach my $exempt_group ( @exempt_groups ) { +% #escape $exempt_group for NAME + <TR> + <TD WIDTH="608" COLSPAN="2"> <INPUT TYPE="checkbox" NAME="tax_<% $exempt_group %>" VALUE="Y" <% $cust_main->tax_exemption($exempt_group) ? 'CHECKED' : '' %>> Tax Exempt (<% $exempt_group %> taxes)<TD> + </TR> +% } + +% unless ( $conf->exists('emailinvoiceonly') ) { + + <TR> + <TD WIDTH="608" COLSPAN="2"><INPUT TYPE="checkbox" NAME="invoicing_list_POST" VALUE="POST" <% + + ( grep { $_ eq 'POST' } @invoicing_list ) + + ? 'CHECKED' + : '' + + %>> Postal mail invoice + + </TD> + </TR> + + <TR> + <TD WIDTH="608" COLSPAN="2"><INPUT TYPE="checkbox" NAME="invoicing_list_FAX" VALUE="FAX" <% + + ( grep { $_ eq 'FAX' } @invoicing_list ) + ? 'CHECKED' + : '' + + %>> Fax invoice + + </TD> + </TR> + +% } + + <TR> + <TD ALIGN="right" WIDTH="200"> + <% $conf->exists('cust_main-require_invoicing_list_email') ? $r : '' %>Email address(es) + </TD> + <TD WIDTH="408"><INPUT TYPE="text" NAME="invoicing_list" VALUE="<% join(', ', grep { $_ !~ /^(POST|FAX)$/ } @invoicing_list ) %>"></TD> + </TR> + + <TR> + <TD ALIGN="right" WIDTH="200">Invoice terms </TD> + <TD WIDTH="408"> + <% include('/elements/select-terms.html', + 'curr_value' => $cust_main->invoice_terms, + ) + %> + </TD> + </TR> + <TR> + <TD ALIGN="right" WIDTH="200">Credit limit </TD> + <TD WIDTH="408"> + <SCRIPT TYPE="text/javascript"> +function toggle(obj) { + obj.form.credit_limit.disabled = obj.checked; +} + </SCRIPT> + <INPUT TYPE="text" NAME="credit_limit" VALUE=<% sprintf('"%.2f"', $cust_main->credit_limit) %><% length($cust_main->credit_limit) ? '' : ' DISABLED' %>> + <INPUT TYPE="checkbox" NAME="no_credit_limit" VALUE=1 onclick="toggle(this)"<% length($cust_main->credit_limit) ? '' : ' CHECKED'%>> Unlimited + </TD> + </TR> + +% if ( $conf->exists('voip-cust_cdr_spools') ) { + <TR> + <TD COLSPAN="2"><INPUT TYPE="checkbox" NAME="spool_cdr" VALUE="Y" <% $cust_main->spool_cdr eq "Y" ? 'CHECKED' : '' %>> Spool CDRs</TD> + </TR> +% } else { + <INPUT TYPE="hidden" NAME="spool_cdr" VALUE="<% $cust_main->spool_cdr %>"> +% } + +% if ( $conf->exists('voip-cust_cdr_squelch') ) { + <TR> + <TD COLSPAN="2"><INPUT TYPE="checkbox" NAME="squelch_cdr" VALUE="Y" <% $cust_main->squelch_cdr eq "Y" ? 'CHECKED' : '' %>> Omit CDRs from invoices</TD> + </TR> +% } else { + <INPUT TYPE="hidden" NAME="squelch_cdr" VALUE="<% $cust_main->squelch_cdr %>"> +% } + +% if ( $conf->exists('voip-cust_email_csv_cdr') ) { + <TR> + <TD COLSPAN="2"><INPUT TYPE="checkbox" NAME="email_csv_cdr" VALUE="Y" <% $cust_main->email_csv_cdr eq "Y" ? 'CHECKED' : '' %>> Attach CDRs as CSV to emailed invoices</TD> + </TR> +% } else { + <INPUT TYPE="hidden" NAME="email_csv_cdr" VALUE="<% $cust_main->email_csv_cdr %>"> +% } + +% if ( $show_term || $cust_main->cdr_termination_percentage ) { + <TR> + <TD ALIGN="right">CDR termination settlement</TD> + <TD><INPUT TYPE = "text" + NAME = "cdr_termination_percentage" + SIZE = 6 + VALUE = "<% $cust_main->cdr_termination_percentage %>" + STYLE = "text-align:right;" + ><B>%</B></TD> + </TR> +% } else { + <INPUT TYPE="hidden" NAME="cdr_termination_percentage" VALUE="<% $cust_main->cdr_termination_percentage %>"> +% } + + </TABLE> + + <% $r %> required fields +% } + +<%once> + +my $paystate_label = FS::Msgcat::_gettext('paystate'); +$paystate_label = 'Bank state' if $paystate_label =~/^paystate$/; + +</%once> +<%init> + +my( $cust_main, %options ) = @_; +my @invoicing_list = @{ $options{'invoicing_list'} }; +my $payinfo = $options{'payinfo'}; +my $conf = new FS::Conf; +my $payby_default = $conf->config('payby-default'); + +my @payby = grep /\w/, $conf->config('payby'); +#@payby = (qw( CARD DCRD CHEK DCHK LECB BILL CASH WEST COMP )) +@payby = (qw( CARD DCRD CHEK DCHK LECB BILL CASH COMP )) + unless @payby; + +my $show_term = ''; +if ( $cust_main->custnum ) { + #false laziness w/view/cust_main/billing.html + my $term_sql = "SELECT COUNT(*) FROM cust_pkg LEFT JOIN part_pkg USING ( pkgpart ) WHERE custnum = ? AND plan = 'cdr_termination' LIMIT 1"; + my $term_sth = dbh->prepare($term_sql) or die dbh->errstr; + $term_sth->execute($cust_main->custnum) or die $term_sth->errstr; + $show_term = $term_sth->fetchrow_arrayref->[0]; +} + +</%init> diff --git a/httemplate/edit/cust_main/birthdate.html b/httemplate/edit/cust_main/birthdate.html new file mode 100644 index 000000000..b4e78e3b9 --- /dev/null +++ b/httemplate/edit/cust_main/birthdate.html @@ -0,0 +1,16 @@ +<% ntable("#cccccc", 2) %> + <% include( '/elements/tr-input-date-field.html', + 'birthdate', + $cust_main->birthdate, + 'Date of Birth', + ( $conf->config('date_format') || "%m/%d/%Y" ), + 1 + ) + %> +</TABLE> +<%init> + +my( $cust_main, %opt ) = @_; +my $conf = new FS::Conf; + +</%init> diff --git a/httemplate/edit/cust_main/bottomfixup.html b/httemplate/edit/cust_main/bottomfixup.html new file mode 100644 index 000000000..1b29c671a --- /dev/null +++ b/httemplate/edit/cust_main/bottomfixup.html @@ -0,0 +1,19 @@ +<% include('/elements/init_overlib.html') %> + +<% include( '/elements/xmlhttp.html', + 'url' => $p.'misc/xmlhttp-cust_main-address_standardize.html', + 'subs' => [ 'address_standardize' ], + #'method' => 'POST', #could get too long? + ) +%> + +<% include( '/elements/xmlhttp.html', + 'url' => $p.'misc/xmlhttp-cust_main-censustract.html', + 'subs' => [ 'censustract' ], + #'method' => 'POST', #could get too long? + ) +%> + +<SCRIPT TYPE="text/javascript"> + <% include('bottomfixup.js') %> +</SCRIPT> diff --git a/httemplate/edit/cust_main/bottomfixup.js b/httemplate/edit/cust_main/bottomfixup.js new file mode 100644 index 000000000..5d06f3c04 --- /dev/null +++ b/httemplate/edit/cust_main/bottomfixup.js @@ -0,0 +1,399 @@ +function bottomfixup(what) { + +%# ../cust_main.cgi + var layervars = new Array( + 'payauto', + 'payinfo', 'payinfo1', 'payinfo2', 'paytype', + 'payname', 'paystate', 'exp_month', 'exp_year', 'paycvv', + 'paystart_month', 'paystart_year', 'payissue', + 'payip', + 'paid' + ); + + var cf = document.CustomerForm; + var payby = cf.payby.options[cf.payby.selectedIndex].value; + for ( f=0; f < layervars.length; f++ ) { + var field = layervars[f]; + copyelement( cf.elements[payby + '_' + field], + cf.elements[field] + ); + } + + //this part does USPS address correction + + // XXX should this be first and should we update the form fields that are + // displayed??? + + var cf = document.CustomerForm; + + var state_el = cf.elements['state']; + var ship_state_el = cf.elements['ship_state']; + + //address_standardize( + var cust_main = new Array( + 'company', cf.elements['company'].value, + 'address1', cf.elements['address1'].value, + 'address2', cf.elements['address2'].value, + 'city', cf.elements['city'].value, + 'state', state_el.options[ state_el.selectedIndex ].value, + 'zip', cf.elements['zip'].value, + + 'ship_company', cf.elements['ship_company'].value, + 'ship_address1', cf.elements['ship_address1'].value, + 'ship_address2', cf.elements['ship_address2'].value, + 'ship_city', cf.elements['ship_city'].value, + 'ship_state', ship_state_el.options[ ship_state_el.selectedIndex ].value, + 'ship_zip', cf.elements['ship_zip'].value + ); + + address_standardize( cust_main, update_address ); + +} + +var standardize_address; + +function update_address(arg) { + + var argsHash = eval('(' + arg + ')'); + + var changed = argsHash['address_standardized']; + var ship_changed = argsHash['ship_address_standardized']; + var error = argsHash['error']; + var ship_error = argsHash['ship_error']; + + + //yay closures + standardize_address = function () { + + var cf = document.CustomerForm; + var state_el = cf.elements['state']; + var ship_state_el = cf.elements['ship_state']; + + if ( changed ) { + cf.elements['company'].value = argsHash['new_company']; + cf.elements['address1'].value = argsHash['new_address1']; + cf.elements['address2'].value = argsHash['new_address2']; + cf.elements['city'].value = argsHash['new_city']; + setselect(cf.elements['state'], argsHash['new_state']); + cf.elements['zip'].value = argsHash['new_zip']; + } + + if ( ship_changed ) { + cf.elements['ship_company'].value = argsHash['new_ship_company']; + cf.elements['ship_address1'].value = argsHash['new_ship_address1']; + cf.elements['ship_address2'].value = argsHash['new_ship_address2']; + cf.elements['ship_city'].value = argsHash['new_ship_city']; + setselect(cf.elements['ship_state'], argsHash['new_ship_state']); + cf.elements['ship_zip'].value = argsHash['new_ship_zip']; + } + + post_standardization(); + + } + + + + if ( changed || ship_changed ) { + +% if ( $conf->exists('cust_main-auto_standardize_address') ) { + + standardize_address(); + +% } else { + + // popup a confirmation popup + + var confirm_change = + '<CENTER><BR><B>Confirm address standardization</B><BR><BR>' + + '<TABLE>'; + + if ( changed ) { + + confirm_change = confirm_change + + '<TR><TH>Entered billing address</TH>' + + '<TH>Standardized billing address</TH></TR>'; + // + '<TR><TD> </TD><TD> </TD></TR>'; + + if ( argsHash['company'] || argsHash['new_company'] ) { + confirm_change = confirm_change + + '<TR><TD>' + argsHash['company'] + + '</TD><TD>' + argsHash['new_company'] + '</TD></TR>'; + } + + confirm_change = confirm_change + + '<TR><TD>' + argsHash['address1'] + + '</TD><TD>' + argsHash['new_address1'] + '</TD></TR>' + + '<TR><TD>' + argsHash['address2'] + + '</TD><TD>' + argsHash['new_address2'] + '</TD></TR>' + + '<TR><TD>' + argsHash['city'] + ', ' + argsHash['state'] + ' ' + argsHash['zip'] + + '</TD><TD>' + argsHash['new_city'] + ', ' + argsHash['new_state'] + ' ' + argsHash['new_zip'] + '</TD></TR>' + + '<TR><TD> </TD><TD> </TD></TR>'; + + } + + if ( ship_changed ) { + + confirm_change = confirm_change + + '<TR><TH>Entered service address</TH>' + + '<TH>Standardized service address</TH></TR>'; + // + '<TR><TD> </TD><TD> </TD></TR>'; + + if ( argsHash['ship_company'] || argsHash['new_ship_company'] ) { + confirm_change = confirm_change + + '<TR><TD>' + argsHash['ship_company'] + + '</TD><TD>' + argsHash['new_ship_company'] + '</TD></TR>'; + } + + confirm_change = confirm_change + + '<TR><TD>' + argsHash['ship_address1'] + + '</TD><TD>' + argsHash['new_ship_address1'] + '</TD></TR>' + + '<TR><TD>' + argsHash['ship_address2'] + + '</TD><TD>' + argsHash['new_ship_address2'] + '</TD></TR>' + + '<TR><TD>' + argsHash['ship_city'] + ', ' + argsHash['ship_state'] + ' ' + argsHash['ship_zip'] + + '</TD><TD>' + argsHash['new_ship_city'] + ', ' + argsHash['new_ship_state'] + ' ' + argsHash['new_ship_zip'] + '</TD></TR>' + + '<TR><TD> </TD><TD> </TD></TR>'; + + } + + var addresses = 'address'; + var height = 268; + if ( changed && ship_changed ) { + addresses = 'addresses'; + height = 396; // #what + } + + confirm_change = confirm_change + + '<TR><TD>' + + '<BUTTON TYPE="button" onClick="post_standardization();"><IMG SRC="<%$p%>images/error.png" ALT=""> Use entered ' + addresses + '</BUTTON>' + + '</TD><TD>' + + '<BUTTON TYPE="button" onClick="standardize_address();"><IMG SRC="<%$p%>images/tick.png" ALT=""> Use standardized ' + addresses + '</BUTTON>' + + '</TD></TR>' + + '<TR><TD COLSPAN=2 ALIGN="center">' + + '<BUTTON TYPE="button" onClick="document.CustomerForm.submitButton.disabled=false; parent.cClick();"><IMG SRC="<%$p%>images/cross.png" ALT=""> Cancel submission</BUTTON></TD></TR>' + + + '</TABLE></CENTER>'; + + overlib( confirm_change, CAPTION, 'Confirm address standardization', STICKY, AUTOSTATUSCAP, CLOSETEXT, '', MIDX, 0, MIDY, 0, DRAGGABLE, WIDTH, 576, HEIGHT, height, BGCOLOR, '#333399', CGCOLOR, '#333399', TEXTSIZE, 3 ); + +% } + + } else { + + post_standardization(); + + } + + +} + +function post_standardization() { + + var cf = document.CustomerForm; + +% if ( $conf->exists('enable_taxproducts') ) { + + if ( new String(cf.elements['<% $taxpre %>zip'].value).length < 10 ) + { + + var country_el = cf.elements['<% $taxpre %>country']; + var country = country_el.options[ country_el.selectedIndex ].value; + var geocode = cf.elements['geocode'].value; + + if ( country == 'CA' || country == 'US' ) { + + var state_el = cf.elements['<% $taxpre %>state']; + var state = state_el.options[ state_el.selectedIndex ].value; + + var url = "cust_main/choose_tax_location.html" + + "?data_vendor=cch-zip" + + ";city=" + cf.elements['<% $taxpre %>city'].value + + ";state=" + state + + ";zip=" + cf.elements['<% $taxpre %>zip'].value + + ";country=" + country + + ";geocode=" + geocode + + ";"; + + // popup a chooser + OLgetAJAX( url, update_geocode, 300 ); + + } else { + + cf.elements['geocode'].value = 'DEFAULT'; + post_geocode(); + + } + + } else { + + cf.elements['geocode'].value = ''; + post_geocode(); + + } + +% } else { + + post_geocode(); + +% } + +} + +function post_geocode() { + +% if ( $conf->exists('cust_main-require_censustract') ) { + + //alert('fetch census tract data'); + var cf = document.CustomerForm; + var state_el = cf.elements['ship_state']; + var census_data = new Array( + 'year', <% $conf->config('census_year') || '2009' %>, + 'address', cf.elements['ship_address1'].value, + 'city', cf.elements['ship_city'].value, + 'state', state_el.options[ state_el.selectedIndex ].value, + 'zip', cf.elements['ship_zip'].value + ); + + censustract( census_data, update_censustract ); + +% }else{ + + document.CustomerForm.submit(); + +% } + +} + +function update_geocode() { + + //yay closures + set_geocode = function (what) { + + var cf = document.CustomerForm; + + //alert(what.options[what.selectedIndex].value); + var argsHash = eval('(' + what.options[what.selectedIndex].value + ')'); + cf.elements['<% $taxpre %>city'].value = argsHash['city']; + setselect(cf.elements['<% $taxpre %>state'], argsHash['state']); + cf.elements['<% $taxpre %>zip'].value = argsHash['zip']; + cf.elements['geocode'].value = argsHash['geocode']; + post_geocode(); + + } + + // popup a chooser + + overlib( OLresponseAJAX, CAPTION, 'Select tax location', STICKY, AUTOSTATUSCAP, CLOSETEXT, '', MIDX, 0, MIDY, 0, DRAGGABLE, WIDTH, 576, HEIGHT, 268, BGCOLOR, '#333399', CGCOLOR, '#333399', TEXTSIZE, 3 ); + +} + +var set_censustract; + +function update_censustract(arg) { + + var argsHash = eval('(' + arg + ')'); + + var cf = document.CustomerForm; + + var msacode = argsHash['msacode']; + var statecode = argsHash['statecode']; + var countycode = argsHash['countycode']; + var tractcode = argsHash['tractcode']; + var error = argsHash['error']; + + var newcensus = + new String(statecode) + + new String(countycode) + + new String(tractcode).replace(/\s$/, ''); // JSON 1 workaround + + set_censustract = function () { + + cf.elements['censustract'].value = newcensus + cf.submit(); + + } + + if (error || cf.elements['censustract'].value != newcensus) { + // popup an entry dialog + + if (error) { newcensus = error; } + newcensus.replace(/.*ndefined.*/, 'Not found'); + + var choose_censustract = + '<CENTER><BR><B>Confirm censustract</B><BR>' + + '<A href="http://maps.ffiec.gov/FFIECMapper/TGMapSrv.aspx?' + + 'census_year=<% $conf->config('census_year') || '2008' %>' + + '&latitude=' + cf.elements['latitude'].value + + '&longitude=' + cf.elements['longitude'].value + + '" target="_blank">Map service module location</A><BR>' + + '<A href="http://maps.ffiec.gov/FFIECMapper/TGMapSrv.aspx?' + + 'census_year=<% $conf->config('census_year') || '2008' %>' + + '&zip_code=' + cf.elements['ship_zip'].value + + '" target="_blank">Map zip code center</A><BR><BR>' + + '<TABLE>'; + + choose_censustract = choose_censustract + + '<TR><TH style="width:50%">Entered census tract</TH>' + + '<TH style="width:50%">Calculated census tract</TH></TR>' + + '<TR><TD>' + cf.elements['censustract'].value + + '</TD><TD>' + newcensus + '</TD></TR>' + + '<TR><TD> </TD><TD> </TD></TR>'; + + choose_censustract = choose_censustract + + '<TR><TD ALIGN="center">' + + '<BUTTON TYPE="button" onClick="document.CustomerForm.submit();"><IMG SRC="<%$p%>images/error.png" ALT=""> Use entered census tract </BUTTON>' + + '</TD><TD ALIGN="center">' + + '<BUTTON TYPE="button" onClick="set_censustract();"><IMG SRC="<%$p%>images/tick.png" ALT=""> Use calculated census tract </BUTTON>' + + '</TD></TR>' + + '<TR><TD COLSPAN=2 ALIGN="center">' + + '<BUTTON TYPE="button" onClick="document.CustomerForm.submitButton.disabled=false; parent.cClick();"><IMG SRC="<%$p%>images/cross.png" ALT=""> Cancel submission</BUTTON></TD></TR>' + + + '</TABLE></CENTER>'; + + overlib( choose_censustract, CAPTION, 'Confirm censustract', STICKY, AUTOSTATUSCAP, CLOSETEXT, '', MIDX, 0, MIDY, 0, DRAGGABLE, WIDTH, 576, HEIGHT, 268, BGCOLOR, '#333399', CGCOLOR, '#333399', TEXTSIZE, 3 ); + + } else { + + cf.submit(); + + } + +} + +function copyelement(from, to) { + if ( from == undefined ) { + to.value = ''; + } else if ( from.type == 'select-one' ) { + to.value = from.options[from.selectedIndex].value; + //alert(from + " (" + from.type + "): " + to.name + " => (" + from.selectedIndex + ") " + to.value); + } else if ( from.type == 'checkbox' ) { + if ( from.checked ) { + to.value = from.value; + } else { + to.value = ''; + } + } else { + if ( from.value == undefined ) { + to.value = ''; + } else { + to.value = from.value; + } + } + //alert(from + " (" + from.type + "): " + to.name + " => " + to.value); +} + +function setselect(el, value) { + + for ( var s = 0; s < el.options.length; s++ ) { + if ( el.options[s].value == value ) { + el.selectedIndex = s; + } + } + +} +<%init> + +my $conf = new FS::Conf; + +my $taxpre = $conf->exists('tax-ship_address') ? 'ship_' : ''; + +</%init> diff --git a/httemplate/edit/cust_main/choose_tax_location.html b/httemplate/edit/cust_main/choose_tax_location.html new file mode 100644 index 000000000..ac475c54b --- /dev/null +++ b/httemplate/edit/cust_main/choose_tax_location.html @@ -0,0 +1,87 @@ +<FORM NAME="choosegeocodeform"> +<CENTER><BR><B>Choose tax location</B><BR><BR> +<P>the geocode is:<% $header %></P> +<P STYLE="<% $style %>"><% $header %></P> + +<SELECT NAME='geocodes' ID='geocodes' STYLE="<% $style %>"> +% foreach my $location (@cust_tax_location) { +% my %value = ( zip => $zip5, +% map { $_ => $location->$_ } +% qw ( city state geocode ) +% ); +% map { $value{$_} = $location{$_} } qw ( city state ) +% if $location{country} eq 'CA'; +% +% my $value = encode_entities(objToJson({ %value }) +% ); +% my $content = ''; +% $content .= $location->$_. ' ' x ( $max{$_} - length($location->$_) ) +% foreach qw( city county state ); +% $content .= $location->cityflag eq 'I' ? 'Y' : 'N' ; +% my $selected = '' ; +% if ($geocode && $location->geocode eq $geocode) { +% $selected = 'SELECTED'; +% } + <OPTION VALUE="<% $value %>" STYLE="<% $style %>" <% $selected %>><% $content %> +% } +</SELECT><BR><BR> + +<TABLE><TR> + <TD> <BUTTON TYPE="button" onClick="set_geocode(document.getElementById('geocodes'));"><IMG SRC="<%$p%>images/tick.png" ALT=""> Set location </BUTTON></TD> + <TD><BUTTON TYPE="button" onClick="document.CustomerForm.submitButton.disabled=false; parent.cClick();"><IMG SRC="<%$p%>images/cross.png" ALT=""> Cancel submission </BUTTON></TD> +</TR> +</TABLE> + +</CENTER> +</FORM> +<%init> + +my $conf = new FS::Conf; + +my %location = (); + +($location{data_vendor}) = $cgi->param('data_vendor') =~ /^([-\w]+)$/; +($location{city}) = $cgi->param('city') =~ /^([\w ]+)$/; +($location{state}) = $cgi->param('state') =~ /^(\w+)$/; +($location{zip}) = $cgi->param('zip') =~ /^([-\w ]+)$/; +($location{country}) = $cgi->param('country') =~ /^([\w ]+)$/; + +my($geocode) = $cgi->param('geocode') =~ /^([\w]+)$/; + +my($zip5, $zip4) = split('-', $location{zip}); + +#only support US & CA +my $hashref = { 'data_vendor' => $location{data_vendor} }; +$hashref->{zip} = $location{country} eq 'CA' ? substr($zip5,0,1) : $zip5, + +my @keys = keys(%$hashref); +my @cust_tax_location = (); +until ( @cust_tax_location ) { + @cust_tax_location = qsearch({ table => 'cust_tax_location', + hashref => $hashref, + order_by => 'LIMIT 50', + }); + last unless scalar(@keys); + delete $hashref->{ shift @keys }; +} + +my %max = ( city => 4, county => 6, state => 5); +foreach my $location (@cust_tax_location) { + foreach ( qw( city county state ) ) { + my $length = length($location->$_); + $max{$_} = ($length > $max{$_}) ? $length : $max{$_}; + } +} +foreach ( qw( city county state ) ) { + $max{$_} = $location{$_} if $location{$_} > $max{$_}; + $max{$_}++; +} + +my $header = ' '; +$header .= $_. ' ' x ( $max{lc($_)} - length($_) ) + foreach qw( City County State ); +$header .= "In city?"; + +my $style = "font-family:monospace;"; + +</%init> diff --git a/httemplate/edit/cust_main/contact.html b/httemplate/edit/cust_main/contact.html new file mode 100644 index 000000000..feb61db8d --- /dev/null +++ b/httemplate/edit/cust_main/contact.html @@ -0,0 +1,150 @@ +<% &ntable("#cccccc") %> + +<TR> + <TH ALIGN="right"><%$r%>Contact name<BR>(last, first)</TH> + <TD COLSPAN=5> + <INPUT TYPE="text" NAME="<%$pre%>last" VALUE="<% $cust_main->get($pre.'last') %>" onChange="<% $onchange %>" <%$disabled%> <%$style%>> , + <INPUT TYPE="text" NAME="<%$pre%>first" VALUE="<% $cust_main->get($pre.'first') %>" onChange="<% $onchange %>" <%$disabled%> <%$style%>> + </TD> +% if ( $conf->exists('show_ss') && !$pre ) { + + <TD ALIGN="right">SS#</TD> + <TD><INPUT TYPE="text" NAME="ss" VALUE="<% $opt{ss} %>" SIZE=11></TD> +% } elsif ( !$pre ) { + + <TD><INPUT TYPE="hidden" NAME="ss" VALUE="<% $opt{ss} %>"></TD> +% } + + +</TR> + +<TR> + <TD ALIGN="right">Company</TD> + <TD COLSPAN=7> + <INPUT TYPE="text" NAME="<%$pre%>company" VALUE="<% $cust_main->get($pre.'company') %>" SIZE=70 onChange="<% $onchange %>" <%$disabled%> <%$style%>> + </TD> +</TR> + +<% include('/elements/location.html', + 'prefix' => $pre, + 'object' => $cust_main, + 'onchange' => $onchange, + 'disabled' => $disabled, + 'style' => \@style, + 'same_checked' => $opt{'same_checked'}, + 'geocode' => $opt{'geocode'}, + 'censustract' => $opt{'censustract'}, + ) +%> + +<TR> + <TD ALIGN="right"><% $daytime_label %></TD> + <TD COLSPAN=5> + <INPUT TYPE="text" NAME="<%$pre%>daytime" VALUE="<% $cust_main->get($pre.'daytime') %>" SIZE=18 onChange="<% $onchange %>" <%$disabled%> <%$style%>> + </TD> +</TR> + +<TR> + <TD ALIGN="right"><% $night_label %></TD> + <TD COLSPAN=5> + <INPUT TYPE="text" NAME="<%$pre%>night" VALUE="<% $cust_main->get($pre.'night') %>" SIZE=18 onChange="<% $onchange %>" <%$disabled%> <%$style%>> + </TD> +</TR> + +<TR> + <TD ALIGN="right">Fax</TD> + <TD COLSPAN=5> + <INPUT TYPE="text" NAME="<%$pre%>fax" VALUE="<% $cust_main->get($pre.'fax') %>" SIZE=12 onChange="<% $onchange %>" <%$disabled%> <%$style%>> + </TD> +</TR> + +% if ( $conf->exists('show_stateid') && !$pre ) { + +<TR> + <TD ALIGN="right"><% $stateid_label %></TD> + <TD><INPUT TYPE="text" NAME="stateid" VALUE="<% $opt{stateid} %>" SIZE=12 onChange="<% $onchange %>" <%$disabled%> <%$style%>></TD> + <TD ALIGN="right"><% $stateid_state_label %></TD> + <TD><% include('/elements/select-state.html', + 'state' => $cust_main->stateid_state, + 'country' => $cust_main->country, + 'prefix' => 'stateid_', + 'onchange' => $onchange, + 'disabled' => $disabled, + 'style' => \@style, + ) + %> + </TD> +</TR> +% } elsif ( !$pre ) { + + <TD><INPUT TYPE="hidden" NAME="stateid" VALUE="<% $opt{stateid} %>"></TD> + <TD><INPUT TYPE="hidden" NAME="stateid_state" VALUE="<% $cust_main->stateid_state %>"></TD> +% } + +</TABLE> +<%$r%>required fields<BR> + +<%init> + +#my( $cust_main, $pre, $onchange, $disabled, %opt ) = @_; +my %opt = @_; +my $cust_main = $opt{'cust_main'}; +my $pre = $opt{'pre'}; +my $onchange = $opt{'onchange'}; +my $disabled = $opt{'disabled'}; +my @style = ( $opt{'style'} ? @{ $opt{'style'} } : () ); + +#push @style, 'background-color: #dddddd' if $disabled; +my $style = scalar(@style) ? 'STYLE="'. join(';', @style). '"' : ''; + +my $conf = new FS::Conf; + +foreach (qw(ss stateid)) { + $opt{$_} = $cust_main->masked($_) unless exists $opt{$_}; +} + +#false laziness with ship state +my $countrydefault = $conf->config('countrydefault') || 'US'; +$cust_main->set($pre.'country', $countrydefault ) + unless $cust_main->get($pre.'country'); + +my $statedefault = $conf->config('statedefault') + || ($countrydefault eq 'US' ? 'CA' : ''); +$cust_main->set($pre.'state', $statedefault ) + unless $cust_main->get($pre.'state') + || $cust_main->get($pre.'country') ne $countrydefault; + +$cust_main->set('stateid_state', $cust_main->state ) + unless $pre || $cust_main->get('stateid_state'); + +$opt{geocode} ||= $cust_main->get('geocode'); + +if ( $conf->exists('cust_main-require_censustract') ) { + $opt{censustract} ||= $cust_main->censustract; +} + +#my($county_html, $state_html, $country_html) = +# FS::cust_main_county::regionselector( $cust_main->get($pre.'county'), +# $cust_main->get($pre.'state'), +# $cust_main->get($pre.'country'), +# $pre, +# $onchange, +# $disabled, +# ); + +my $daytime_label = FS::Msgcat::_gettext('daytime') =~ /^(daytime)?$/ + ? 'Day Phone' + : FS::Msgcat::_gettext('daytime'); +my $night_label = FS::Msgcat::_gettext('night') =~/^(night)?$/ + ? 'Night Phone' + : FS::Msgcat::_gettext('night') || 'Night Phone'; +my $stateid_label = FS::Msgcat::_gettext('stateid') =~ /^(stateid)?$/ + ? 'Driver’s License' + : FS::Msgcat::_gettext('stateid') || 'Driver’s License'; +my $stateid_state_label = FS::Msgcat::_gettext('stateid_state') =~ /^(stateid_state)?$/ + ? 'Driver’s License State' + : FS::Msgcat::_gettext('stateid_state') || 'Driver’s License State'; + +my $r = qq!<font color="#ff0000">*</font> !; + +</%init> diff --git a/httemplate/edit/cust_main/first_pkg.html b/httemplate/edit/cust_main/first_pkg.html new file mode 100644 index 000000000..0de33c025 --- /dev/null +++ b/httemplate/edit/cust_main/first_pkg.html @@ -0,0 +1,55 @@ +% if ( @part_pkg ) { + + <BR><BR> + <FONT SIZE="+1"><B>First package</B></FONT> + <% ntable("#cccccc") %> + + <TR> + <TD COLSPAN=2> + <% include('first_pkg/select-part_pkg.html', + 'part_pkg' => \@part_pkg, + %opt, + # map { $_ => $opt{$_} } qw( pkgpart_svcpart saved_domsvc ) + ) + %> + +% } +<%init> + +my( $cust_main, %opt ) = @_; + +# pry the wrong place for this logic. also pretty expensive + +#false laziness, copied from FS::cust_pkg::order +my $pkgpart; +my $agentnum = ''; +my @agents = $FS::CurrentUser::CurrentUser->agents; +if ( scalar(@agents) == 1 ) { + # $pkgpart->{PKGPART} is true iff $custnum may purchase PKGPART + $pkgpart = $agents[0]->pkgpart_hashref; + $agentnum = $agents[0]->agentnum; +} else { + #can't know (agent not chosen), so, allow all + $agentnum = 'all'; + my %typenum; + foreach my $agent ( @agents ) { + next if $typenum{$agent->typenum}++; + $pkgpart->{$_}++ foreach keys %{ $agent->pkgpart_hashref } + } +} +#eslaf + +my @first_svc = ( 'svc_acct', 'svc_phone' ); + +my @part_pkg = + grep { $_->svcpart(\@first_svc) + && ( $pkgpart->{ $_->pkgpart } + || $agentnum eq 'all' + || ( $agentnum ne 'all' && $agentnum && $_->agentnum + && $_->agentnum == $agentnum + ) + ) + } + qsearch( 'part_pkg', { 'disabled' => '' }, '', 'ORDER BY pkg' ); # case? + +</%init> diff --git a/httemplate/edit/cust_main/first_pkg/select-part_pkg.html b/httemplate/edit/cust_main/first_pkg/select-part_pkg.html new file mode 100644 index 000000000..871e1cdee --- /dev/null +++ b/httemplate/edit/cust_main/first_pkg/select-part_pkg.html @@ -0,0 +1,170 @@ +<% include('/elements/xmlhttp.html', + 'url' => $url_prefix.'misc/svc_acct-domains.cgi', + 'subs' => [ $opt{'prefix'}. 'get_domains' ], + ) +%> + +<% include('/elements/xmlhttp.html', + 'url' => $url_prefix.'misc/part_svc-columns.cgi', + 'subs' => [ $opt{'prefix'}. 'get_part_svc' ], + ) +%> + +<INPUT TYPE="hidden" NAME="svcdb" VALUE=""> + +<SCRIPT TYPE="text/javascript"> + + function selopt(what,value,text,selected) { + var optionName = new Option(text, value, false, selected); + var length = what.length; + what.options[length] = optionName; + } + + var pkgpart_svcpart2svcdb = { +% foreach my $pkgpart ( map $_->pkgpart, @part_pkg ) { + "<% $pkgpart_svcpart{$pkgpart} %>":"<% $svcdb{$pkgpart} %>", +% } + '':'' + }; + + function <% $opt{'prefix'} %>pkgpart_svcpart_changed_too(what,selected) { + + <% $opt{'onchange'} %>; + + pkgpart_svcpart = what.options[what.selectedIndex].value; + + var svcdb = pkgpart_svcpart2svcdb[pkgpart_svcpart]; + + what.form.svcdb.value = svcdb; + + if ( svcdb == 'svc_acct' ) { + + // go get the new domains + function <% $opt{'prefix'} %>update_domains(domains) { + + // blank the current domain list + for ( var i = what.form.<% $opt{'prefix'} %>domsvc.length; i >= 0; i-- ) + what.form.<% $opt{'prefix'} %>domsvc.options[i] = null; + + // add the new domains + var domainArray = eval('(' + domains + ')' ); + for ( var s = 0; s < domainArray.length; s=s+2 ) { + var domainLabel = domainArray[s+1]; + if ( domainLabel == "" ) + domainLabel = '(n/a)'; + selopt( what.form.<% $opt{'prefix'} %>domsvc, + domainArray[s], + domainLabel, + (domainArray[s] == selected) ? true : false + ); + } + + } + + <% $opt{'prefix'} %>get_domains( pkgpart_svcpart, + <% $opt{'prefix'} %>update_domains + ); + + } else if ( svcdb == 'svc_phone' ) { + + function <% $opt{'prefix'} %>update_svc_phone(part_svc_column) { + var colArray = eval('(' + part_svc_column + ')' ); + for ( var s = 0; s < colArray.length; s=s+3 ) { + var name = colArray[s]; + var flag = colArray[s+1]; + var value = colArray[s+2]; + var td_label = document.getElementById(name+'_label_td'); + var td = document.getElementById(name+'_td'); + var input = document.getElementById(name); + if ( flag == 'D' ) { + if ( ! input.value ) { input.value = value; } + td_label.style.display = '' + td.style.display = '' + } else if ( flag == 'F' ) { + input.value = value; + td_label.style.display = 'none' + td.style.display = 'none' + } else { + td_label.style.display = '' + td.style.display = '' + } + } + } + + <% $opt{'prefix'} %>get_part_svc( pkgpart_svcpart, + <% $opt{'prefix'} %>update_svc_phone + ); + + } + + } + +</SCRIPT> + +<% include( '/elements/selectlayers.html', + 'field' => $opt{'prefix'}. 'pkgpart_svcpart', + 'curr_value' => $opt{pkgpart_svcpart}, + 'options' => \@options, + 'labels' => \%labels, + 'html_between' => '</TD></TR></TABLE>', + #'onchange' => $opt{'prefix'}. 'pkgpart_svcpart_changed(this,0);', + 'onchange' => $opt{'prefix'}. 'pkgpart_svcpart_changed_too(what,0)', + + 'layer_callback' => $layer_callback, + 'layermap' => \%layermap, + ) +%> + +<SCRIPT TYPE="text/javascript"> + pkgpart_svcpart_changed_too( document.CustomerForm.pkgpart_svcpart, + <% $opt{saved_domsvc} %> + ); +</SCRIPT> + +<%init> + +my %opt = @_; + +foreach my $opt (qw( svc_part pkgparts saved_pkgpart saved_domsvc prefix)) { + $opt{$_} = '' unless exists($opt{$_}) && defined($opt{$_}); +} +$opt{saved_domsvc} = 0 unless $opt{saved_domsvc}; + +my $url_prefix = $opt{'relurls'} ? '' : $p; + +my @part_pkg = @{$opt{'part_pkg'}}; + +my @first_svc = ( 'svc_acct', 'svc_phone' ); + +my %pkgpart_svcpart = (); +my %svcdb = (); +my %layermap = (); +foreach my $part_pkg ( @part_pkg ) { + my $pkgpart = $part_pkg->pkgpart; + my $pkgpart_svcpart = $pkgpart. "_". $part_pkg->svcpart(\@first_svc); + $pkgpart_svcpart{$pkgpart} = $pkgpart_svcpart; + $svcdb{$pkgpart} = $part_pkg->part_svc(\@first_svc)->svcdb; + $layermap{$pkgpart_svcpart} = $svcdb{$pkgpart}; +} + +my @options = ( '', map $pkgpart_svcpart{ $_->pkgpart }, @part_pkg ); +my %labels = ( '' => ( $opt{'empty_label'} || '(none)' ), + map { $pkgpart_svcpart{ $_->pkgpart } => $_->pkg_comment } + @part_pkg + ); + +my $layer_callback = sub { + my $layer = shift; + #$layer_fields, $layer_values, $layer_prefix + +# my( $pkgpart, $svcpart ) = split('_', $layer); +# my $svcdb = $svcdb{$pkgpart}; + my $svcdb = $layer; + + return '' unless $svcdb; #'<BR><BR><BR><BR><BR>' + + #full path cause we're being slung around as a coderef (mason closures?) + include("/edit/cust_main/first_pkg/$svcdb.html", %opt, ); +}; + +</%init> diff --git a/httemplate/edit/cust_main/first_pkg/svc_acct.html b/httemplate/edit/cust_main/first_pkg/svc_acct.html new file mode 100644 index 000000000..150d4c043 --- /dev/null +++ b/httemplate/edit/cust_main/first_pkg/svc_acct.html @@ -0,0 +1,88 @@ +<% ntable("#cccccc") %> + + <TR> + <TD ALIGN="right">Username</TD> + <TD> + <INPUT TYPE = "text" + NAME = "username" + VALUE = "<% $opt{'username'} %>" + SIZE = <% $ulen2 %> + MAXLENGTH = <% $ulen %> + > + </TD> + </TR> + + <TR> + <TD ALIGN="right">Domain</TD> + <TD> + <SELECT NAME="domsvc"> + <OPTION>(none)</OPTION> + </SELECT> + </TD> + </TR> + + <TR> + <TD ALIGN="right">Password</TD> + <TD> + <INPUT TYPE = "text" + NAME = "_password" + VALUE = "<% $opt{'password'} %>" + SIZE = <% $pmax2 %> + MAXLENGTH = <% $passwordmax %>> +% unless ( $opt{'password_verify'} ) { + (blank to generate) +% } + </TD> + </TR> + +% if ( $opt{'password_verify'} ) { + <TR> + <TD ALIGN="right">Re-enter Password</TD> + <TD> + <INPUT TYPE = "text" + NAME = "_password2" + VALUE = "<% $opt{'password2'} %>" + SIZE = <% $pmax2 %> + MAXLENGTH = <% $passwordmax %>> + </TD> + </TR> +% } + +% if ( $conf->exists('security_phrase') ) { + <TR> + <TD ALIGN="right">Security Phrase</TD> + <TD><INPUT TYPE="text" NAME="sec_phrase" VALUE="<% $opt{'sec_phrase'} %>"> + </TD> + </TR> +% } else { + <INPUT TYPE="hidden" NAME="sec_phrase" VALUE=""> +% } + +% if ( $conf->exists('svc_acct-disable_access_number') ) { + <INPUT TYPE="hidden" NAME="popnum" VALUE=""> +% } else { + <TR> + <TD ALIGN="right">Access number</TD> +%# XXX should gain "area code" selection and labels on the dropdowns + <TD><% FS::svc_acct_pop::popselector($opt{'popnum'}) %></TD> + </TR> +% } + +</TABLE> + +<%init> + +#use FS::svc_acct_pop; + +my( %opt ) = @_; + +my $conf = new FS::Conf; + +#false laziness: (mostly) copied from edit/svc_acct.cgi +#$ulen = $svc_acct->dbdef_table->column('username')->length; +my $ulen = dbdef->table('svc_acct')->column('username')->length; +my $ulen2 = $ulen+2; +my $passwordmax = $conf->config('passwordmax') || 8; +my $pmax2 = $passwordmax + 2; + +</%init> diff --git a/httemplate/edit/cust_main/first_pkg/svc_phone.html b/httemplate/edit/cust_main/first_pkg/svc_phone.html new file mode 100644 index 000000000..70e013ece --- /dev/null +++ b/httemplate/edit/cust_main/first_pkg/svc_phone.html @@ -0,0 +1,82 @@ +<% ntable("#cccccc") %> + +%#XXX this should be hidden or something in most/all cases + <TR> + <TD ALIGN="right" ID="countrycode_label_td">Country code</TD> + <TD ID="countrycode_td"> + <INPUT TYPE = "text" + NAME = "countrycode" + ID = "countrycode" + VALUE = "<% $opt{'countrycode'} %>" + SIZE = 4 + MAXLENGTH = 3 + > + </TD> + </TR> + +%#we don't know the svcpart until the dropdown is changed :/ +%#<% include('/elements/tr-select-did.html', +%# 'label' => 'Phone number', +%# 'curr_value' => $opt{'phonenum'}, +%# ) +%#%> + <TR> + <TD ALIGN="right" ID="phonenum_label_td">Phone Number</TD> + <TD ID="phonenum_td"> + <INPUT TYPE = "text" + NAME = "phonenum" + ID = "phonenum" + VALUE = "<% $opt{'phonenum'} %>" + SIZE = 21 + MAXLENGTH = 20 + > + </TD> + </TR> + + <TR> + <TD ALIGN="right" ID="sip_password_label_td">SIP password</TD> + <TD ID="sip_password_td"> + <INPUT TYPE = "text" + NAME = "sip_password" + ID = "sip_password" + VALUE = "<% $opt{'sip_password'} %>" + MAXLENGTH = 80 + > + </TD> + </TR> + + <TR> + <TD ALIGN="right" ID="pin_label_td">Voicemail PIN</TD> + <TD ID="pin_td"> + <INPUT TYPE = "text" + NAME = "pin" + ID = "pin" + VALUE = "<% $opt{'pin'} %>" + SIZE = 5 + MAXLENGTH = 4 + > + </TD> + </TR> + +%#XXX this should be hidden or something in most/all cases + <TR> + <TD ALIGN="right" ID="phone_name_label_td">Name</TD> + <TD ID="phone_name_td"> + <INPUT TYPE = "text" + NAME = "phone_name" + ID = "phone_name" + VALUE = "<% $opt{'phone_name'} %>" + MAXLENGTH = 80 + > + </TD> + </TR> + +</TABLE> + +<%init> + +my( %opt ) = @_; + +#my $conf = new FS::Conf; + +</%init> diff --git a/httemplate/edit/cust_main/top_misc.html b/httemplate/edit/cust_main/top_misc.html new file mode 100644 index 000000000..441a36334 --- /dev/null +++ b/httemplate/edit/cust_main/top_misc.html @@ -0,0 +1,117 @@ +<% &ntable("#cccccc") %> + +%# tags +<% include('/elements/tr-select-cust_tag.html', + 'custnum' => $custnum, + 'cgi' => $cgi, + ) +%> + +%# agent +<% include('/elements/tr-select-agent.html', + 'curr_value' => $cust_main->agentnum, + 'label' => "<B>${r}Agent</B>", + 'empty_label' => 'Select agent', + 'disable_empty' => ( $cust_main->agentnum ? 1 : 0 ), + 'viewall_right' => 'None', #override default 'View customers of all agents' + ) +%> + +%# agent_custid +% if ( $conf->exists('cust_main-edit_agent_custid') ) { + + <TR> + <TD ALIGN="right">Customer identifier</TD> + <TD><INPUT TYPE="text" NAME="agent_custid" VALUE="<% $cust_main->agent_custid %>"></TD> + </TR> + +% } else { + + <INPUT TYPE="hidden" NAME="agent_custid" VALUE="<% $cust_main->agent_custid %>"> + +% } + +%# class +<% include('/elements/tr-select-cust_class.html', + 'curr_value' => $cust_main->classnum, + 'label' => "Class", + #'empty_label' => '(none)', + #'disable_empty' => + ) +%> + +%# referral (advertising source) +%my $refnum = $cust_main->refnum || $conf->config('referraldefault') || 0; +%if ( $custnum && ! $conf->exists('editreferrals') ) { + + <INPUT TYPE="hidden" NAME="refnum" VALUE="<% $refnum %>"> + +% } else { + + <% include('/elements/tr-select-part_referral.html', + 'curr_value' => $refnum + ) + %> +% } + + +%# referring customer +%my $referring_cust_main = ''; +%if ( $cust_main->referral_custnum +% and $referring_cust_main = +% qsearchs('cust_main', { custnum => $cust_main->referral_custnum } ) +% and ! $curuser->access_right('Edit referring customer') +%) { + + <TR> + <TD ALIGN="right">Referring customer</TD> + <TD> + <A HREF="<% popurl(1) %>/cust_main.cgi?<% $cust_main->referral_custnum %>"><% $cust_main->referral_custnum %>: <% $referring_cust_main->name %></A> + </TD> + </TR> + <INPUT TYPE="hidden" NAME="referral_custnum" VALUE="<% $cust_main->referral_custnum %>"> + +% } elsif ( ! $conf->exists('disable_customer_referrals') ) { + + <TR> + <TD ALIGN="right">Referring customer</TD> + <TD> + <!-- <INPUT TYPE="text" NAME="referral_custnum" VALUE=""> --> + <% include('/elements/search-cust_main.html', + 'field_name' => 'referral_custnum', + 'curr_value' => $cust_main->referral_custnum, + ) + %> + </TD> + </TR> + +% } else { + <INPUT TYPE="hidden" NAME="referral_custnum" VALUE=""> +% } + +%# signup date +% if ( $conf->exists('cust_main-edit_signupdate') ) { + <% include('/elements/tr-input-date-field.html', { + 'name' => 'signupdate', + 'value' => $cust_main->signupdate, + 'label' => 'Signup date', + 'format' => ( $conf->config('date_format') || "%m/%d/%Y" ), + }) + %> +% } + +</TABLE> + +<%init> + +my( $cust_main, %opt ) = @_; + +my $custnum = $opt{'custnum'}; + +my $conf = new FS::Conf; + +my $curuser = $FS::CurrentUser::CurrentUser; + +my $r = qq!<font color="#ff0000">*</font> !; + +</%init> |