diff options
Diffstat (limited to 'httemplate/edit')
34 files changed, 1496 insertions, 463 deletions
diff --git a/httemplate/edit/REAL_cust_pkg.cgi b/httemplate/edit/REAL_cust_pkg.cgi index 0d2f1c238..d9b7579f6 100755 --- a/httemplate/edit/REAL_cust_pkg.cgi +++ b/httemplate/edit/REAL_cust_pkg.cgi @@ -1,6 +1,6 @@ <!-- mason kludge --> <% -# <!-- $Id: REAL_cust_pkg.cgi,v 1.4 2002-07-08 13:07:40 ivan Exp $ --> +# <!-- $Id: REAL_cust_pkg.cgi,v 1.7 2003-11-19 12:21:09 ivan Exp $ --> my $error =''; my $pkgnum = ''; @@ -30,6 +30,15 @@ print header('Package Edit'); #, menubar( # 'Main Menu' => popurl(2) #)); +%> + + <LINK REL="stylesheet" TYPE="text/css" HREF="../elements/calendar-win2k-2.css" TITLE="win2k-2"> + <SCRIPT TYPE="text/javascript" SRC="../elements/calendar_stripped.js"></SCRIPT> + <SCRIPT TYPE="text/javascript" SRC="../elements/calendar-en.js"></SCRIPT> + <SCRIPT TYPE="text/javascript" SRC="../elements/calendar-setup.js"></SCRIPT> + +<% + #print info my($susp,$cancel,$expire)=( $cust_pkg->getfield('susp'), @@ -45,6 +54,9 @@ print '<FORM NAME="formname" ACTION="process/REAL_cust_pkg.cgi" METHOD="POST">', print qq!<FONT SIZE="+1" COLOR="#ff0000">Error: $error</FONT>! if $error; +#my $format = "%c %z (%Z)"; +my $format = "%m/%d/%Y %T %z (%Z)"; + print ntable("#cccccc",2), '<TR><TD ALIGN="right">Package number</TD><TD BGCOLOR="#ffffff">', $pkgnum, '</TD></TR>', @@ -55,15 +67,29 @@ print ntable("#cccccc",2), '<TR><TD ALIGN="right">Order taker</TD><TD BGCOLOR="#ffffff">', $otaker, '</TD></TR>', '<TR><TD ALIGN="right">Setup date</TD><TD>'. - '<INPUT TYPE="text" NAME="setup" SIZE=32 VALUE="', - ( $setup ? time2str("%c %z (%Z)",$setup) : "" ), '"></TD></TR>', - '<TR><TD ALIGN="right">Next bill date</TD><TD>', - '<INPUT TYPE="text" NAME="bill" SIZE=32 VALUE="', - ( $bill ? time2str("%c %z (%Z)",$bill) : "" ), '"></TD></TR>', -; + '<INPUT TYPE="text" NAME="setup" SIZE=32 ID="setup_text" VALUE="', + ( $setup ? time2str($format, $setup) : "" ), '">'. + ' <IMG SRC="../images/calendar.png" ID="setup_button" STYLE="cursor: pointer" TITLE="Select date">'. + '</TD></TR>'; + +print '<TR><TD ALIGN="right">Last bill date</TD><TD>', + '<INPUT TYPE="text" NAME="last_bill" SIZE=32 ID="last_bill_text" VALUE="', + ( $cust_pkg->last_bill + ? time2str($format, $cust_pkg->last_bill) + : "" ), + '">'. + ' <IMG SRC="../images/calendar.png" ID="last_bill_button" STYLE="cursor: pointer" TITLE="Select date">'. + '</TD></TR>' + if $cust_pkg->dbdef_table->column('last_bill'); + +print '<TR><TD ALIGN="right">Next bill date</TD><TD>', + '<INPUT TYPE="text" NAME="bill" SIZE=32 ID="bill_text" VALUE="', + ( $bill ? time2str($format, $bill) : "" ), '">'. + ' <IMG SRC="../images/calendar.png" ID="bill_button" STYLE="cursor: pointer" TITLE="Select date">'. + '</TD></TR>'; print '<TR><TD ALIGN="right">Suspension date</TD><TD BGCOLOR="#ffffff">', - time2str("%D",$susp), '</TD></TR>' + time2str($format, $susp), '</TD></TR>' if $susp; #print '<TR><TD ALIGN="right">Expiration date</TD><TD BGCOLOR="#ffffff">', @@ -71,18 +97,34 @@ print '<TR><TD ALIGN="right">Suspension date</TD><TD BGCOLOR="#ffffff">', # if $expire; print '<TR><TD ALIGN="right">Expiration date'. '</TD><TD>', - '<INPUT TYPE="text" NAME="expire" SIZE=32 VALUE="', - ( $expire ? time2str("%c %z (%Z)",$expire) : "" ), '">'. + '<INPUT TYPE="text" NAME="expire" SIZE=32 ID="expire_text" VALUE="', + ( $expire ? time2str($format, $expire) : "" ), '">'. + ' <IMG SRC="../images/calendar.png" ID="expire_button" STYLE="cursor: pointer" TITLE="Select date">'. '<BR><FONT SIZE=-1>(will <b>cancel</b> this package'. ' when the date is reached)</FONT>'. '</TD></TR>'; print '<TR><TD ALIGN="right">Cancellation date</TD><TD BGCOLOR="#ffffff">', - time2str("%D",$cancel), '</TD></TR>' + time2str($format, $cancel), '</TD></TR>' if $cancel; %> </TABLE> +<SCRIPT TYPE="text/javascript"> +<% + my @cal = qw( setup bill expire ); + push @cal, 'last_bill' + if $cust_pkg->dbdef_table->column('last_bill'); + foreach my $cal (@cal) { +%> + Calendar.setup({ + inputField: "<%= $cal %>_text", + ifFormat: "%m/%d/%Y", + button: "<%= $cal %>_button", + align: "BR" + }); +<% } %> +</SCRIPT> <BR><INPUT TYPE="submit" VALUE="Apply Changes"> </FORM> </BODY> diff --git a/httemplate/edit/agent.cgi b/httemplate/edit/agent.cgi index 449456cdd..8a1cb2ae1 100755 --- a/httemplate/edit/agent.cgi +++ b/httemplate/edit/agent.cgi @@ -16,59 +16,64 @@ if ( $cgi->param('error') ) { my $action = $agent->agentnum ? 'Edit' : 'Add'; my $hashref = $agent->hashref; -print header("$action Agent", menubar( +%> + +<%= header("$action Agent", menubar( 'Main Menu' => $p, 'View all agents' => $p. 'browse/agent.cgi', -)); +)) %> -print qq!<FONT SIZE="+1" COLOR="#ff0000">Error: !, $cgi->param('error'), - "</FONT>" - if $cgi->param('error'); +<% if ( $cgi->param('error') ) { %> +<FONT SIZE="+1" COLOR="#ff0000">Error: <%= $cgi->param('error') %></FONT> +<% } %> -print '<FORM ACTION="', popurl(1), 'process/agent.cgi" METHOD=POST>', - qq!<INPUT TYPE="hidden" NAME="agentnum" VALUE="$hashref->{agentnum}">!, - "Agent #", $hashref->{agentnum} ? $hashref->{agentnum} : "(NEW)"; +<FORM ACTION="<%=popurl(1)%>process/agent.cgi" METHOD=POST> +<INPUT TYPE="hidden" NAME="agentnum" VALUE="<%= $hashref->{agentnum} %>"> +Agent #<%= $hashref->{agentnum} ? $hashref->{agentnum} : "(NEW)" %> -print &ntable("#cccccc", 2, ''), <<END; +<%= &ntable("#cccccc", 2, '') %> <TR> <TH ALIGN="right">Agent</TH> - <TD><INPUT TYPE="text" NAME="agent" SIZE=32 VALUE="$hashref->{agent}"></TD> + <TD><INPUT TYPE="text" NAME="agent" SIZE=32 VALUE="<%= $hashref->{agent} %>"></TD> </TR> <TR> <TH ALIGN="right">Agent type</TH> <TD><SELECT NAME="typenum" SIZE=1> -END -foreach my $agent_type (qsearch('agent_type',{})) { - print "<OPTION VALUE=". $agent_type->typenum; - print " SELECTED" - if $hashref->{typenum} && ( $hashref->{typenum} == $agent_type->typenum ); - print ">", $agent_type->getfield('typenum'), ": ", - $agent_type->getfield('atype'),"\n"; -} +<% foreach my $agent_type (qsearch('agent_type',{})) { %> + <OPTION VALUE="<%= $agent_type->typenum %>"<%= ( $hashref->{typenum} && ( $hashref->{typenum} == $agent_type->typenum ) ) ? ' SELECTED' : '' %>> + <%= $agent_type->getfield('typenum') %>: <%= $agent_type->getfield('atype') %> +<% } %> -print <<END; </SELECT></TD> </TR> +<% if ( dbdef->table('agent')->column('disabled') ) { %> + <TR> + <TD ALIGN="right">Disable</TD> + <TD><INPUT TYPE="checkbox" NAME="disabled" VALUE="Y"<%= $hashref->{disabled} eq 'Y' ? ' CHECKED' : '' %>></TD> + </TR> +<% } %> <TR> <TD ALIGN="right"><!--Frequency--></TD> - <TD><INPUT TYPE="hidden" NAME="freq" VALUE="$hashref->{freq}"></TD> + <TD><INPUT TYPE="hidden" NAME="freq" VALUE="<%= $hashref->{freq} %>"></TD> </TR> <TR> <TD ALIGN="right"><!--Program--></TD> - <TD><INPUT TYPE="hidden" NAME="prog" VALUE="$hashref->{prog}"></TD> + <TD><INPUT TYPE="hidden" NAME="prog" VALUE="<%= $hashref->{prog} %>"></TD> </TR> +<% if ( dbdef->table('agent')->column('username') ) { %> + <TR> + <TD ALIGN="right">Agent interface username</TD> + <TD><INPUT TYPE="text" NAME="username" VALUE="<%= $hashref->{username} %>"></TD> + </TR> + <TR> + <TD ALIGN="right">Agent interface password</TD> + <TD><INPUT TYPE="text" NAME="_password" VALUE="<%= $hashref->{_password} %>"></TD> + </TR> +<% } %> </TABLE> -END -print qq!<BR><INPUT TYPE="submit" VALUE="!, - $hashref->{agentnum} ? "Apply changes" : "Add agent", - qq!">!; - -print <<END; +<BR><INPUT TYPE="submit" VALUE="<%= $hashref->{agentnum} ? "Apply changes" : "Add agent" %>"> </FORM> </BODY> </HTML> -END - -%> diff --git a/httemplate/edit/cust_main.cgi b/httemplate/edit/cust_main.cgi index cf8de2f13..857e769a3 100755 --- a/httemplate/edit/cust_main.cgi +++ b/httemplate/edit/cust_main.cgi @@ -17,6 +17,7 @@ my $conf = new FS::Conf; my $error = ''; my($custnum, $username, $password, $popnum, $cust_main, $saved_pkgpart); +my(@invoicing_list); if ( $cgi->param('error') ) { $error = $cgi->param('error'); $cust_main = new FS::cust_main ( { @@ -32,15 +33,23 @@ if ( $cgi->param('error') ) { $username = $cgi->param('username'); $password = $cgi->param('_password'); $popnum = $cgi->param('popnum'); + @invoicing_list = split( /\s*,\s*/, $cgi->param('invoicing_list') ); } elsif ( $cgi->keywords ) { #editing my( $query ) = $cgi->keywords; $query =~ /^(\d+)$/; $custnum=$1; $cust_main = qsearchs('cust_main', { 'custnum' => $custnum } ); + if ( $cust_main->dbdef_table->column('paycvv') + && length($cust_main->paycvv) ) { + my $paycvv = $cust_main->paycvv; + $paycvv =~ s/./*/g; + $cust_main->paycvv($paycvv); + } $saved_pkgpart = 0; $username = ''; $password = ''; $popnum = 0; + @invoicing_list = $cust_main->invoicing_list; } else { $custnum=''; $cust_main = new FS::cust_main ( {} ); @@ -50,6 +59,7 @@ if ( $cgi->param('error') ) { $username = ''; $password = ''; $popnum = 0; + @invoicing_list = (); } $cgi->delete_all(); my $action = $custnum ? 'Edit' : 'Add'; @@ -57,7 +67,7 @@ my $action = $custnum ? 'Edit' : 'Add'; # top my $p1 = popurl(1); -print header("Customer $action", ''); +print header("Customer $action", '', ' onUnload="myclose()"'); print qq!<FONT SIZE="+1" COLOR="#ff0000">Error: !, $error, "</FONT>" if $error; @@ -71,9 +81,11 @@ print qq!<FORM ACTION="${p1}process/cust_main.cgi" METHOD=POST NAME="form1">!, my $r = qq!<font color="#ff0000">*</font> !; -my @agents = qsearch( 'agent', {} ); +my %agent_search = dbdef->table('agent')->column('disabled') + ? ( 'disabled' => '' ) : (); +my @agents = qsearch( 'agent', \%agent_search ); #die "No agents created!" unless @agents; -die "You have not created any agents. You must create at least one agent before adding a customer. Go to ". popurl(2). "browse/agent.cgi and create one or more agents." unless @agents; +eidiot "You have not created any agents (or all agents are disabled). You must create at least one agent before adding a customer. Go to ". popurl(2). "browse/agent.cgi and create one or more agents." unless @agents; my $agentnum = $cust_main->agentnum || $agents[0]->agentnum; #default to first if ( scalar(@agents) == 1 ) { print qq!<INPUT TYPE="hidden" NAME="agentnum" VALUE="$agentnum">!; @@ -99,7 +111,7 @@ if ( $custnum && ! $conf->exists('editreferrals') ) { } else { my(@referrals) = qsearch('part_referral',{}); if ( scalar(@referrals) == 0 ) { - die "You have not created any advertising sources. You must create at least one advertising source before adding a customer. Go to ". popurl(2). "browse/part_referral.cgi and create one or more advertising sources."; + eidiot "You have not created any advertising sources. You must create at least one advertising source before adding a customer. Go to ". popurl(2). "browse/part_referral.cgi and create one or more advertising sources."; } elsif ( scalar(@referrals) == 1 ) { $refnum ||= $referrals[0]->refnum; print qq!<INPUT TYPE="hidden" NAME="refnum" VALUE="$refnum">!; @@ -120,9 +132,11 @@ if ( $custnum && ! $conf->exists('editreferrals') ) { #referring customer #print qq!<BR><BR>Referring Customer: !; -if ( $cust_main->referral_custnum ) { - my $referring_cust_main = - qsearchs('cust_main', { custnum => $cust_main->referral_custnum } ); +my $referring_cust_main = ''; +if ( $cust_main->referral_custnum + and $referring_cust_main = + qsearchs('cust_main', { custnum => $cust_main->referral_custnum } ) +) { print '<BR><BR>Referring Customer: <A HREF="'. popurl(1). '/cust_main.cgi?'. $cust_main->referral_custnum. '">'. $cust_main->referral_custnum. ': '. @@ -177,8 +191,10 @@ END my $countrydefault = $conf->config('countrydefault') || 'US'; $cust_main->country( $countrydefault ) unless $cust_main->country; -$cust_main->state( $conf->config('statedefault') || 'CA' ) - unless $cust_main->state || $cust_main->country ne 'US'; +my $statedefault = $conf->config('statedefault') + || ($countrydefault eq 'US' ? 'CA' : ''); +$cust_main->state( $statedefault ) + unless $cust_main->state || $cust_main->country ne $countrydefault; my($county_html, $state_html, $country_html) = FS::cust_main_county::regionselector( $cust_main->county, @@ -195,10 +211,13 @@ my($daytime,$night,$fax)=( $cust_main->fax, ); +my $daytime_label = FS::Msgcat::_gettext('daytime') || 'Day Phone'; +my $night_label = FS::Msgcat::_gettext('night') || 'Night Phone'; + print <<END; <TR><TH ALIGN="right">${r}Country</TH><TD>$country_html</TD></TR> -<TR><TD ALIGN="right">Day Phone</TD><TD COLSPAN=5><INPUT TYPE="text" NAME="daytime" VALUE="$daytime" SIZE=18></TD></TR> -<TR><TD ALIGN="right">Night Phone</TD><TD COLSPAN=5><INPUT TYPE="text" NAME="night" VALUE="$night" SIZE=18></TD></TR> +<TR><TD ALIGN="right">$daytime_label</TD><TD COLSPAN=5><INPUT TYPE="text" NAME="daytime" VALUE="$daytime" SIZE=18></TD></TR> +<TR><TD ALIGN="right">$night_label</TD><TD COLSPAN=5><INPUT TYPE="text" NAME="night" VALUE="$night" SIZE=18></TD></TR> <TR><TD ALIGN="right">Fax</TD><TD COLSPAN=5><INPUT TYPE="text" NAME="fax" VALUE="$fax" SIZE=12></TD></TR> END @@ -231,7 +250,7 @@ END print '<BR>Service address ', '(<INPUT TYPE="checkbox" NAME="same" VALUE="Y" onClick="samechanged(this)"'; - unless ( $cust_main->ship_last ) { + unless ( $cust_main->ship_last && $cgi->param('same') ne 'Y' ) { print ' CHECKED'; foreach ( qw( last first company address1 address2 city county state zip country @@ -272,8 +291,9 @@ END #false laziness with regular state $cust_main->ship_country( $countrydefault ) unless $cust_main->ship_country; - $cust_main->ship_state( $conf->config('statedefault') || 'CA' ) - unless $cust_main->ship_state || $cust_main->ship_country ne 'US'; + $cust_main->ship_state( $statedefault ) + unless $cust_main->ship_state + || $cust_main->ship_country ne $countrydefault; my($ship_county_html, $ship_state_html, $ship_country_html) = FS::cust_main_county::regionselector( $cust_main->ship_county, @@ -294,8 +314,8 @@ END print <<END; <TR><TH ALIGN="right">${r}Country</TH><TD>$ship_country_html</TD></TR> - <TR><TD ALIGN="right">Day Phone</TD><TD COLSPAN=5><INPUT TYPE="text" NAME="ship_daytime" VALUE="$ship_daytime" SIZE=18 onChange="changed(this)"></TD></TR> - <TR><TD ALIGN="right">Night Phone</TD><TD COLSPAN=5><INPUT TYPE="text" NAME="ship_night" VALUE="$ship_night" SIZE=18 onChange="changed(this)"></TD></TR> + <TR><TD ALIGN="right">$daytime_label</TD><TD COLSPAN=5><INPUT TYPE="text" NAME="ship_daytime" VALUE="$ship_daytime" SIZE=18 onChange="changed(this)"></TD></TR> + <TR><TD ALIGN="right">$night_label</TD><TD COLSPAN=5><INPUT TYPE="text" NAME="ship_night" VALUE="$ship_night" SIZE=18 onChange="changed(this)"></TD></TR> <TR><TD ALIGN="right">Fax</TD><TD COLSPAN=5><INPUT TYPE="text" NAME="ship_fax" VALUE="$ship_fax" SIZE=12 onChange="changed(this)"></TD></TR> END @@ -326,7 +346,9 @@ sub expselect { $return .= ">$_"; } $return .= qq!</SELECT>/<SELECT NAME="$prefix!. qq!_year" SIZE="1">!; - for ( 2001 .. 2037 ) { + my @t = localtime; + my $thisYear = $t[5] + 1900; + for ( ($thisYear > $y && $y > 0 ? $y : $thisYear) .. 2037 ) { $return .= "<OPTION"; $return .= " SELECTED" if $_ == $y; $return .= ">$_"; @@ -336,48 +358,129 @@ sub expselect { $return; } -print "<BR>Billing information", &itable("#cccccc"), - qq!<TR><TD><INPUT TYPE="checkbox" NAME="tax" VALUE="Y"!; -print qq! CHECKED! if $cust_main->tax eq "Y"; -print qq!>Tax Exempt</TD></TR>!; -print qq!<TR><TD><INPUT TYPE="checkbox" NAME="invoicing_list_POST" VALUE="POST"!; -my @invoicing_list = $cust_main->invoicing_list; -print qq! CHECKED! - if ( ! @invoicing_list && ! $conf->exists('disablepostalinvoicedefault') ) - || grep { $_ eq 'POST' } @invoicing_list; -print qq!>Postal mail invoice</TD></TR>!; -my $invoicing_list = join(', ', grep { $_ ne 'POST' } @invoicing_list ); -print qq!<TR><TD>Email invoice <INPUT TYPE="text" NAME="invoicing_list" VALUE="$invoicing_list"></TD></TR>!; - -print "<TR><TD>Billing type</TD></TR>", - "</TABLE>", - &table("#cccccc"), "<TR>"; - -my($payinfo, $payname)=( - $cust_main->payinfo, - $cust_main->payname, -); +my $payby_default = $conf->config('payby-default'); + +if ( $payby_default eq 'HIDE' ) { + + $cust_main->payby('BILL') unless $cust_main->payby; + + foreach my $field (qw( tax payby )) { + print qq!<INPUT TYPE="hidden" NAME="$field" VALUE="!. + $cust_main->getfield($field). '">'; + } + + print qq!<INPUT TYPE="hidden" NAME="invoicing_list" VALUE="!. + join(', ', $cust_main->invoicing_list). '">'; + + foreach my $payby (qw( CARD DCRD CHEK DCHK LECB BILL COMP )) { + foreach my $field (qw( payinfo payname )) { + print qq!<INPUT TYPE="hidden" NAME="${payby}_$field" VALUE="!. + $cust_main->getfield($field). '">'; + } + + #false laziness w/expselect + my( $m, $y ); + my $date = $cust_main->paydate || '12-2037'; + if ( $date =~ /^(\d{4})-(\d{1,2})-\d{1,2}$/ ) { #PostgreSQL date format + ( $m, $y ) = ( $2, $1 ); + } elsif ( $date =~ /^(\d{1,2})-(\d{1,2}-)?(\d{4}$)/ ) { + ( $m, $y ) = ( $1, $3 ); + } else { + die "unrecognized expiration date format: $date"; + } + + print qq!<INPUT TYPE="hidden" NAME="${payby}_month" VALUE="$m">!. + qq!<INPUT TYPE="hidden" NAME="${payby}_year" VALUE="$y">!; + + } -my %payby = ( - 'CARD' => qq!Credit card<BR>${r}<INPUT TYPE="text" NAME="CARD_payinfo" VALUE="" MAXLENGTH=19><BR>${r}Exp !. expselect("CARD"). qq!<BR>${r}Name on card<BR><INPUT TYPE="text" NAME="CARD_payname" VALUE="">!, - 'BILL' => qq!Billing<BR>P.O. <INPUT TYPE="text" NAME="BILL_payinfo" VALUE=""><BR>${r}Exp !. expselect("BILL", "12-2037"). qq!<BR>Attention<BR><INPUT TYPE="text" NAME="BILL_payname" VALUE="">!, - 'COMP' => qq!Complimentary<BR>${r}Approved by<INPUT TYPE="text" NAME="COMP_payinfo" VALUE=""><BR>${r}Exp !. expselect("COMP"), +} else { + + print "<BR>Billing information", &itable("#cccccc"), + qq!<TR><TD><INPUT TYPE="checkbox" NAME="tax" VALUE="Y"!; + print qq! CHECKED! if $cust_main->tax eq "Y"; + print qq!>Tax Exempt</TD></TR><TR><TD>!. + qq!<INPUT TYPE="checkbox" NAME="invoicing_list_POST" VALUE="POST"!; + + #my @invoicing_list = $cust_main->invoicing_list; + print qq! CHECKED! + if ( ! @invoicing_list && ! $conf->exists('disablepostalinvoicedefault') ) + || grep { $_ eq 'POST' } @invoicing_list; + print qq!>Postal mail invoice</TD></TR>!; + my $invoicing_list = join(', ', grep { $_ ne 'POST' } @invoicing_list ); + print qq!<TR><TD>Email invoice <INPUT TYPE="text" NAME="invoicing_list" VALUE="$invoicing_list"></TD></TR>!; + + print "<TR><TD>Billing type</TD></TR>", + "</TABLE>", '<script language="JavaScript"><!-- + var mywindow = -1; + function myopen(filename,windowname,properties) { + myclose(); + mywindow = window.open(filename,windowname,properties); + } + function myclose() { + if ( mywindow != -1 ) + mywindow.close(); + mywindow = -1; + } + + //--></script>', + &table("#cccccc"), "<TR>"; + + my($payinfo, $payname)=( + $cust_main->payinfo, + $cust_main->payname, + ); + + my %payby = ( + 'CARD' => qq!Credit card (automatic)<BR>${r}<INPUT TYPE="text" NAME="CARD_payinfo" VALUE="" MAXLENGTH=19><BR>${r}Exp !. expselect("CARD"). qq!<BR>${r}Name on card<BR><INPUT TYPE="text" NAME="CARD_payname" VALUE="">!, + 'DCRD' => qq!Credit card (on-demand)<BR>${r}<INPUT TYPE="text" NAME="DCRD_payinfo" VALUE="" MAXLENGTH=19><BR>${r}Exp !. expselect("DCRD"). qq!<BR>${r}Name on card<BR><INPUT TYPE="text" NAME="DCRD_payname" VALUE="">!, + 'CHEK' => qq!Electronic check (automatic)<BR>${r}Account number <INPUT TYPE="text" NAME="CHEK_payinfo1" VALUE=""><BR>${r}ABA/Routing code <INPUT TYPE="text" NAME="CHEK_payinfo2" VALUE="" SIZE=10 MAXLENGTH=9><INPUT TYPE="hidden" NAME="CHEK_month" VALUE="12"><INPUT TYPE="hidden" NAME="CHEK_year" VALUE="2037"><BR>${r}Bank name <INPUT TYPE="text" NAME="CHEK_payname" VALUE="">!, + 'DCHK' => qq!Electronic check (on-demand)<BR>${r}Account number <INPUT TYPE="text" NAME="DCHK_payinfo1" VALUE=""><BR>${r}ABA/Routing code <INPUT TYPE="text" NAME="DCHK_payinfo2" VALUE="" SIZE=10 MAXLENGTH=9><INPUT TYPE="hidden" NAME="DCHK_month" VALUE="12"><INPUT TYPE="hidden" NAME="DCHK_year" VALUE="2037"><BR>${r}Bank name <INPUT TYPE="text" NAME="DCHK_payname" VALUE="">!, + 'LECB' => qq!Phone bill billing<BR>${r}Phone number <INPUT TYPE="text" BANE="LECB_payinfo" VALUE="" MAXLENGTH=15 SIZE=16><INPUT TYPE="hidden" NAME="LECB_month" VALUE="12"><INPUT TYPE="hidden" NAME="LECB_year" VALUE="2037"><INPUT TYPE="hidden" NAME="LECB_payname" VALUE="">!, + 'BILL' => qq!Billing<BR>P.O. <INPUT TYPE="text" NAME="BILL_payinfo" VALUE=""><BR><INPUT TYPE="hidden" NAME="BILL_month" VALUE="12"><INPUT TYPE="hidden" NAME="BILL_year" VALUE="2037">Attention<BR><INPUT TYPE="text" NAME="BILL_payname" VALUE="">!, + 'COMP' => qq!Complimentary<BR>${r}Approved by<INPUT TYPE="text" NAME="COMP_payinfo" VALUE=""><BR>${r}Exp !. expselect("COMP"), ); -my %paybychecked = ( - 'CARD' => qq!Credit card<BR>${r}<INPUT TYPE="text" NAME="CARD_payinfo" VALUE="$payinfo" MAXLENGTH=19><BR>${r}Exp !. expselect("CARD", $cust_main->paydate). qq!<BR>${r}Name on card<BR><INPUT TYPE="text" NAME="CARD_payname" VALUE="$payname">!, - 'BILL' => qq!Billing<BR>P.O. <INPUT TYPE="text" NAME="BILL_payinfo" VALUE="$payinfo"><BR>${r}Exp !. expselect("BILL", $cust_main->paydate). qq!<BR>Attention<BR><INPUT TYPE="text" NAME="BILL_payname" VALUE="$payname">!, - 'COMP' => qq!Complimentary<BR>${r}Approved by<INPUT TYPE="text" NAME="COMP_payinfo" VALUE="$payinfo"><BR>${r}Exp !. expselect("COMP", $cust_main->paydate), + + if ( $cust_main->dbdef_table->column('paycvv') ) { + foreach my $payby ( grep { exists $payby{$_} } qw(CARD DCRD) ) { #1.4/1.5 bs + $payby{$payby} .= qq!<BR>CVV2 (<A HREF="javascript:myopen('../docs/cvv2.html','cvv2','toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=yes,copyhistory=no,width=480,height=288')">help</A>) <INPUT TYPE="text" NAME=${payby}_paycvv VALUE="" SIZE=4 MAXLENGTH=4>!; + } + } + + my( $account, $aba ) = split('@', $payinfo); + + my %paybychecked = ( + 'CARD' => qq!Credit card (automatic)<BR>${r}<INPUT TYPE="text" NAME="CARD_payinfo" VALUE="$payinfo" MAXLENGTH=19><BR>${r}Exp !. expselect("CARD", $cust_main->paydate). qq!<BR>${r}Name on card<BR><INPUT TYPE="text" NAME="CARD_payname" VALUE="$payname">!, + 'DCRD' => qq!Credit card (on-demand)<BR>${r}<INPUT TYPE="text" NAME="DCRD_payinfo" VALUE="$payinfo" MAXLENGTH=19><BR>${r}Exp !. expselect("DCRD", $cust_main->paydate). qq!<BR>${r}Name on card<BR><INPUT TYPE="text" NAME="DCRD_payname" VALUE="$payname">!, + 'CHEK' => qq!Electronic check (automatic)<BR>${r}Account number <INPUT TYPE="text" NAME="CHEK_payinfo1" VALUE="$account"><BR>${r}ABA/Routing code <INPUT TYPE="text" NAME="CHEK_payinfo2" VALUE="$aba" SIZE=10 MAXLENGTH=9><INPUT TYPE="hidden" NAME="CHEK_month" VALUE="12"><INPUT TYPE="hidden" NAME="CHEK_year" VALUE="2037"><BR>${r}Bank name <INPUT TYPE="text" NAME="CHEK_payname" VALUE="$payname">!, + 'DCHK' => qq!Electronic check (on-demand)<BR>${r}Account number <INPUT TYPE="text" NAME="DCHK_payinfo1" VALUE="$account"><BR>${r}ABA/Routing code <INPUT TYPE="text" NAME="DCHK_payinfo2" VALUE="$aba" SIZE=10 MAXLENGTH=9><INPUT TYPE="hidden" NAME="DCHK_month" VALUE="12"><INPUT TYPE="hidden" NAME="DCHK_year" VALUE="2037"><BR>${r}Bank name <INPUT TYPE="text" NAME="DCHK_payname" VALUE="$payname">!, + 'LECB' => qq!Phone bill billing<BR>${r}Phone number <INPUT TYPE="text" BANE="LECB_payinfo" VALUE="$payinfo" MAXLENGTH=15 SIZE=16><INPUT TYPE="hidden" NAME="LECB_month" VALUE="12"><INPUT TYPE="hidden" NAME="LECB_year" VALUE="2037"><INPUT TYPE="hidden" NAME="LECB_payname" VALUE="">!, + 'BILL' => qq!Billing<BR>P.O. <INPUT TYPE="text" NAME="BILL_payinfo" VALUE="$payinfo"><BR><INPUT TYPE="hidden" NAME="BILL_month" VALUE="12"><INPUT TYPE="hidden" NAME="BILL_year" VALUE="2037">Attention<BR><INPUT TYPE="text" NAME="BILL_payname" VALUE="$payname">!, + 'COMP' => qq!Complimentary<BR>${r}Approved by<INPUT TYPE="text" NAME="COMP_payinfo" VALUE="$payinfo"><BR>${r}Exp !. expselect("COMP", $cust_main->paydate), ); -for (qw(CARD BILL COMP)) { - print qq!<TD VALIGN=TOP><INPUT TYPE="radio" NAME="payby" VALUE="$_"!; - if ($cust_main->payby eq "$_") { - print qq! CHECKED> $paybychecked{$_}</TD>!; - } else { - print qq!> $payby{$_}</TD>!; + + if ( $cust_main->dbdef_table->column('paycvv') ) { + my $paycvv = $cust_main->paycvv; + + foreach my $payby ( grep { exists $payby{$_} } qw(CARD DCRD) ) { #1.4/1.5 bs + $paybychecked{$payby} .= qq!<BR>CVV2 (<A HREF="javascript:myopen('../docs/cvv2.html','cvv2','toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=yes,copyhistory=no,width=480,height=288')">help</A>) <INPUT TYPE="text" NAME=${payby}_paycvv VALUE="$paycvv" SIZE=4 MAXLENGTH=4>!; + } + } + + + $cust_main->payby($payby_default) unless $cust_main->payby; + for (qw(CARD DCRD CHEK DCHK LECB BILL COMP)) { + print qq!<TD VALIGN=TOP><INPUT TYPE="radio" NAME="payby" VALUE="$_"!; + if ($cust_main->payby eq "$_") { + print qq! CHECKED> $paybychecked{$_}</TD>!; + } else { + print qq!> $payby{$_}</TD>!; + } } -} -print "</TR></TABLE>$r required fields for each billing type"; + print "</TR></TABLE>$r required fields for each billing type"; + +} if ( defined $cust_main->dbdef_table->column('comments') ) { print "<BR><BR>Comments", &itable("#cccccc"), @@ -422,7 +525,7 @@ unless ( $custnum ) { foreach my $part_pkg ( @part_pkg ) { print qq!<OPTION VALUE="!, # $part_pkg->pkgpart. "_". $pkgpart{ $part_pkg->pkgpart }, '"'; - $part_pkg->pkgpart. "_". $part_pkg->svcpart, '"'; + $part_pkg->pkgpart. "_". $part_pkg->svcpart('svc_acct'), '"'; print " SELECTED" if $saved_pkgpart && ( $part_pkg->pkgpart == $saved_pkgpart ); print ">", $part_pkg->pkg, " - ", $part_pkg->comment; } diff --git a/httemplate/edit/cust_main_county.cgi b/httemplate/edit/cust_main_county.cgi index 7ef37a48d..4bcfcbe9b 100755 --- a/httemplate/edit/cust_main_county.cgi +++ b/httemplate/edit/cust_main_county.cgi @@ -15,12 +15,27 @@ print qq!<FORM ACTION="!, popurl(1), <TH><FONT SIZE=-1>Country</FONT></TH> <TH><FONT SIZE=-1>State</FONT></TH> <TH><FONT SIZE=-1>County</FONT></TH> - <TH><FONT SIZE=-1>Taxclass</FONT></TH> + <TH><FONT SIZE=-1>Taxclass</FONT><BR><FONT SIZE=-2>(per-package classification)</FONT></TH> +END + +if ( dbdef->table('cust_main_county')->column('taxname') ) { + print '<TH><FONT SIZE=-1>Tax name</FONT><BR><FONT SIZE=-2>(printed on invoices)</FONT></TH>'; +} + +print <<END; <TH><FONT SIZE=-1>Tax</FONT></TH> <TH><FONT SIZE=-1>Exempt<BR>per<BR>month</TH> - </TR> END +if ( dbdef->table('cust_main_county')->column('setuptax') ) { + print '<TH><FONT SIZE=-1>Setup<BR>fee<BR>exempt</TH>'; +} +if ( dbdef->table('cust_main_county')->column('recurtax') ) { + print '<TH><FONT SIZE=-1>Recurring<BR>fee<BR>exempt</TH>'; +} + +print '</TR>'; + foreach my $cust_main_county ( sort { $a->country cmp $b->country or $a->state cmp $b->state or $a->county cmp $b->county @@ -46,10 +61,27 @@ END : ' BGCOLOR="#cccccc">(ALL)' , "</TD>"; - print qq!<TD><INPUT TYPE="text" NAME="tax!, $hashref->{taxnum}, - qq!" VALUE="!, $hashref->{tax}, qq!" SIZE=6 MAXLENGTH=6>%</TD>!; - print qq!<TD>\$<INPUT TYPE="text" NAME="exempt_amount!, $hashref->{taxnum}, - qq!" VALUE="!, $hashref->{exempt_amount}||0, qq!" SIZE=6></TD>!; + print qq!<TD><INPUT TYPE="text" NAME="taxname!, $hashref->{taxnum}, + qq!" VALUE="!, $hashref->{taxname}, qq!"></TD>! + if dbdef->table('cust_main_county')->column('taxname'); + + print qq!<TD><TABLE><TR><TD><INPUT TYPE="text" NAME="tax!, $hashref->{taxnum}, + qq!" VALUE="!, $hashref->{tax}, qq!" SIZE=6 MAXLENGTH=6></TD><TD>%</TD></TR></TABLE></TD>!; + print qq!<TD><TABLE><TR><TD>\$</TD><TD><INPUT TYPE="text" NAME="exempt_amount!, $hashref->{taxnum}, + qq!" VALUE="!, $hashref->{exempt_amount}||0, qq!" SIZE=6></TD></TR></TABLE></TD>!; + + print qq!<TD><INPUT TYPE="checkbox" NAME="setuptax!. $hashref->{taxnum}. + '" VALUE="Y"'. + ( $hashref->{setuptax} =~ /^Y$/i ? ' CHECKED' : '' ). + '></TD>' + if dbdef->table('cust_main_county')->column('setuptax'); + + print qq!<TD><INPUT TYPE="checkbox" NAME="recurtax!. $hashref->{taxnum}. + '" VALUE="Y"'. + ( $hashref->{recurtax} =~ /^Y$/i ? ' CHECKED' : '' ). + '></TD>' + if dbdef->table('cust_main_county')->column('recurtax'); + print '</TR>'; } diff --git a/httemplate/edit/part_bill_event.cgi b/httemplate/edit/part_bill_event.cgi index 324daeb90..48ed7916b 100755 --- a/httemplate/edit/part_bill_event.cgi +++ b/httemplate/edit/part_bill_event.cgi @@ -20,7 +20,7 @@ if ( $query && $query =~ /^(\d+)$/ ) { } else { $part_bill_event ||= new FS::part_bill_event {}; } -$action ||= $part_bill_event->pkgpart ? 'Edit' : 'Add'; +$action ||= $part_bill_event->eventpart ? 'Edit' : 'Add'; my $hashref = $part_bill_event->hashref; print header("$action Invoice Event Definition", menubar( @@ -41,7 +41,7 @@ print ntable("#cccccc",2), <<END; <TR><TD ALIGN="right">Payby</TD><TD><SELECT NAME="payby"> END -for (qw(CARD BILL COMP)) { +for (qw(CARD DCRD CHEK DCHK LECB BILL COMP)) { print qq!<OPTION VALUE="$_"!; if ($part_bill_event->payby eq $_) { print " SELECTED>$_</OPTION>"; @@ -108,9 +108,15 @@ tie my %events, 'Tie::IxHash', 'weight' => 30, }, - 'realtime-card-cybercash' => { - 'name' => '(<b>deprecated</b>) Run card with <a href="http://www.cybercash.com/cashregister">CyberCash CashRegister</a> realtime gateway', - 'code' => '$cust_bill->realtime_card_cybercash();', + 'realtime-check' => { + 'name' => 'Run check with a <a href="http://search.cpan.org/search?mode=module&query=Business%3A%3AOnlinePayment">Business::OnlinePayment</a> realtime gateway', + 'code' => '$cust_bill->realtime_ach();', + 'weight' => 30, + }, + + 'realtime-lec' => { + 'name' => 'Run phone bill ("LEC") billing with a <a href="http://search.cpan.org/search?mode=module&query=Business%3A%3AOnlinePayment">Business::OnlinePayment</a> realtime gateway', + 'code' => '$cust_bill->realtime_lec();', 'weight' => 30, }, @@ -134,6 +140,30 @@ tie my %events, 'Tie::IxHash', 'weight' => 50, }, + 'send_csv_ftp' => { + 'name' => 'Upload CSV invoice data to an FTP server', + 'code' => '$cust_bill->send_csv( protocol => \'ftp\', + server => \'%%%ftpserver%%%\', + username => \'%%%ftpusername%%%\', + password => \'%%%ftppassword%%%\', + dir => \'%%%ftpdir%%%\' );', + 'html' => + '<TABLE BORDER=0><TR><TD ALIGN="right">FTP server: </TD>'. + '<TD><INPUT TYPE="text" NAME="ftpserver" VALUE="%%%ftpserver%%%">'. + '</TD></TR>'. + '<TR><TD ALIGN="right">FTP username: </TD><TD>'. + '<INPUT TYPE="text" NAME="ftpusername" VALUE="%%%ftpusername%%%">'. + '</TD></TR>'. + '<TR><TD ALIGN="right">FTP password: </TD><TD>'. + '<INPUT TYPE="text" NAME="ftppassword" VALUE="%%%ftppassword%%%">'. + '</TD></TR>'. + '<TR><TD ALIGN="right">FTP directory: </TD>'. + '<TD><INPUT TYPE="text" NAME="ftpdir" VALUE="%%%ftpdir%%%">'. + '</TD></TR>'. + '</TABLE>', + 'weight' => 50, + }, + 'bill' => { 'name' => 'Generate invoices (normally only used with a <i>Late Fee</i> event)', 'code' => '$cust_main->bill();', diff --git a/httemplate/edit/part_export.cgi b/httemplate/edit/part_export.cgi index 486bd4300..4d0c7391f 100644 --- a/httemplate/edit/part_export.cgi +++ b/httemplate/edit/part_export.cgi @@ -49,24 +49,33 @@ my $widget = new HTML::Widgets::SelectLayers( my $label = $optinfo->{label}; my $type = defined($optinfo->{type}) ? $optinfo->{type} : 'text'; my $value = $cgi->param($option) - || $part_export->option($option) - || (exists $optinfo->{default} ? $optinfo->{default} : ''); + || ( $part_export->exportnum && $part_export->option($option) ) + || ( (exists $optinfo->{default} && !$part_export->exportnum) + ? $optinfo->{default} + : '' + ); $html .= qq!<TR><TD ALIGN="right">$label</TD><TD>!; if ( $type eq 'select' ) { $html .= qq!<SELECT NAME="$option">!; foreach my $select_option ( @{$optinfo->{options}} ) { #if ( ref($select_option) ) { #} else { - $selected = $select_option eq $value ? ' SELECTED' : ''; + my $selected = $select_option eq $value ? ' SELECTED' : ''; $html .= qq!<OPTION VALUE="$select_option"$selected>!. qq!$select_option</OPTION>!; #} } $html .= '</SELECT>'; } elsif ( $type eq 'textarea' ) { - $html .= qq!<TEXTAREA NAME="$option">$value</TEXTAREA>!; + $html .= qq!<TEXTAREA NAME="$option" COLS=80 ROWS=8 WRAP="virtual">!. + encode_entities($value). '</TEXTAREA>'; } elsif ( $type eq 'text' ) { - $html .= qq!<INPUT TYPE="text" NAME="$option" VALUE="$value" SIZE=64>!; + $html .= qq!<INPUT TYPE="text" NAME="$option" VALUE="!. + encode_entities($value). '" SIZE=64>'; + } elsif ( $type eq 'checkbox' ) { + $html .= qq!<INPUT TYPE="checkbox" NAME="$option" VALUE="1"!; + $html .= ' CHECKED' if $value; + $html .= '>'; } else { $html .= "unknown type $type"; } diff --git a/httemplate/edit/part_pkg.cgi b/httemplate/edit/part_pkg.cgi index b6ecff2d0..8416b3546 100755 --- a/httemplate/edit/part_pkg.cgi +++ b/httemplate/edit/part_pkg.cgi @@ -66,12 +66,52 @@ print '<FORM NAME="dummy">'; #print qq!<INPUT TYPE="hidden" NAME="pkgpart" VALUE="$hashref->{pkgpart}">!, print "Package Part #", $hashref->{pkgpart} ? $hashref->{pkgpart} : "(NEW)"; -print ntable("#cccccc",2), <<END; -<TR><TD ALIGN="right">Package (customer-visable)</TD><TD><INPUT TYPE="text" NAME="pkg" SIZE=32 VALUE="$hashref->{pkg}"></TD></TR> -<TR><TD ALIGN="right">Comment (customer-hidden)</TD><TD><INPUT TYPE="text" NAME="comment" SIZE=32 VALUE="$hashref->{comment}"></TD></TR> -<TR><TD ALIGN="right">Frequency (months) of recurring fee</TD><TD><INPUT TYPE="text" NAME="freq" VALUE="$hashref->{freq}" SIZE=3> <I>0=no recurring fee, 1=monthly, 3=quarterly, 12=yearly</TD></TR> -<TR><TD ALIGN="right">Setup fee tax exempt</TD><TD> -END +#false laziness w/view/cust_main.cgi +my %freq; +tie %freq, 'Tie::IxHash', + '0' => '(no recurring fee)', + '1d' => 'daily', + '1w' => 'weekly', + '2w' => 'biweekly (every 2 weeks)', + '1' => 'monthly', + '2' => 'bimonthly (every 2 months)', + '3' => 'quarterly (every 3 months)', + '6' => 'semiannually (every 6 months)', + '12' => 'annually', + '24' => 'biannually (every 2 years)', +; +if ( $part_pkg->dbdef_table->column('freq')->type =~ /(int)/i ) { + delete $freq{$_} foreach grep { ! /^\d+$/ } keys %freq; +} + +%> +<%= ntable("#cccccc",2) %> + <TR> + <TD ALIGN="right">Package (customer-visible)</TD> + <TD> + <INPUT TYPE="text" NAME="pkg" SIZE=32 VALUE="<%= $part_pkg->pkg %>"> + </TD> + </TR> + <TR> + <TD ALIGN="right">Comment (customer-hidden)</TD> + <TD> + <INPUT TYPE="text" NAME="comment" SIZE=32 VALUE="<%=$part_pkg->comment%>"> + </TD> + </TR> + <TR> + <TD ALIGN="right">Recurring fee frequency </TD> + <TD> + <SELECT NAME="freq"> + <% foreach my $freq ( keys %freq ) { %> + <OPTION VALUE="<%= $freq %>"<%= $freq eq $part_pkg->freq ? ' SELECTED' : '' %>><%= $freq{$freq} %> + <% } %> + </SELECT> + </TD> + </TR> + <TR> + <TD ALIGN="right">Setup fee tax exempt</TD> + <TD> +<% print '<INPUT TYPE="checkbox" NAME="setuptax" VALUE="Y"'; print ' CHECKED' if $hashref->{setuptax} eq "Y"; @@ -112,9 +152,11 @@ print ' CHECKED' if $hashref->{disabled} eq "Y"; print '>'; print '</TD></TR></TABLE>'; -my $thead = "\n\n". ntable('#cccccc', 2). <<END; -<TR><TH BGCOLOR="#dcdcdc"><FONT SIZE=-1>Quan.</FONT></TH><TH BGCOLOR="#dcdcdc">Service</TH></TR> -END +my $thead = "\n\n". ntable('#cccccc', 2). + '<TR><TH BGCOLOR="#dcdcdc"><FONT SIZE=-1>Quan.</FONT></TH>'; +$thead .= '<TH BGCOLOR="#dcdcdc"><FONT SIZE=-1>Primary</FONT></TH>' + if dbdef->table('pkg_svc')->column('primary_svc'); +$thead .= '<TH BGCOLOR="#dcdcdc">Service</TH></TR>'; #unless ( $cgi->param('clone') ) { #dunno why... @@ -131,13 +173,15 @@ my $columns = 3; my @part_svc = qsearch( 'part_svc', { 'disabled' => '' } ); foreach my $part_svc ( @part_svc ) { my $svcpart = $part_svc->svcpart; - my $pkg_svc = qsearchs( 'pkg_svc', { - 'pkgpart' => $cgi->param('clone') || $part_pkg->pkgpart, + my $pkgpart = $cgi->param('clone') || $part_pkg->pkgpart; + my $pkg_svc = $pkgpart && qsearchs( 'pkg_svc', { + 'pkgpart' => $pkgpart, 'svcpart' => $svcpart, } ) || new FS::pkg_svc ( { - 'pkgpart' => $cgi->param('clone') || $part_pkg->pkgpart, - 'svcpart' => $svcpart, - 'quantity' => 0, + 'pkgpart' => $pkgpart, + 'svcpart' => $svcpart, + 'quantity' => 0, + 'primary_svc' => '', }); #? #next unless $pkg_svc; @@ -149,7 +193,13 @@ foreach my $part_svc ( @part_svc ) { print '<TR>'; # if $count == 0 ; print qq!<TD><INPUT TYPE="text" NAME="pkg_svc$svcpart" SIZE=4 MAXLENGTH=3 VALUE="!, $cgi->param("pkg_svc$svcpart") || $pkg_svc->quantity || 0, - qq!"></TD><TD><A HREF="part_svc.cgi?!,$part_svc->svcpart, + qq!"></TD>!; + if ( dbdef->table('pkg_svc')->column('primary_svc') ) { + print qq!<TD><INPUT TYPE="radio" NAME="pkg_svc_primary" VALUE="$svcpart"!; + print ' CHECKED' if $pkg_svc->primary_svc =~ /^Y/i; + print '></TD>'; + } + print qq!<TD><A HREF="part_svc.cgi?!,$part_svc->svcpart, qq!">!, $part_svc->getfield('svc'), "</A></TD></TR>"; # print "</TABLE></TD><TD>$thead" if ++$count == int(scalar(@part_svc) / 2); $count+=1; @@ -355,6 +405,114 @@ tie my %plans, 'Tie::IxHash', }, + 'sqlradacct_hour' => { + 'name' => 'Base charge plus charge per-hour (and for data) from an external sqlradius radacct table', + 'fields' => { + 'setup_fee' => { 'name' => 'Setup fee for this package', + 'default' => 0, + }, + 'recur_flat' => { 'name' => 'Base monthly charge for this package', + 'default' => 0, + }, + 'recur_included_hours' => { 'name' => 'Hours included', + 'default' => 0, + }, + 'recur_hourly_charge' => { 'name' => 'Additional charge per hour', + 'default' => 0, + }, + 'recur_included_input' => { 'name' => 'Input megabytes included', + 'default' => 0, + }, + 'recur_input_charge' => { 'name' => + 'Additional charge per input megabyte', + 'default' => 0, + }, + 'recur_included_output' => { 'name' => 'Output megabytes included', + 'default' => 0, + }, + 'recur_output_charge' => { 'name' => + 'Additional charge per output megabyte', + 'default' => 0, + }, + 'recur_included_total' => { 'name' => + 'Total input+output megabytes included', + 'default' => 0, + }, + 'recur_total_charge' => { 'name' => + 'Additional charge per input+output megabyte', + 'default' => 0, + }, + }, + 'fieldorder' => [qw( setup_fee recur_flat recur_included_hours recur_hourly_charge recur_included_input recur_input_charge recur_included_output recur_output_charge recur_included_total recur_total_charge )], + 'setup' => 'what.setup_fee.value', + 'recur' => '\'my $last_bill = $cust_pkg->last_bill; my $hours = $cust_pkg->seconds_since_sqlradacct($last_bill, $sdate ) / 3600 - \' + what.recur_included_hours.value + \'; $hours = 0 if $hours < 0; my $input = $cust_pkg->attribute_since_sqlradacct($last_bill, $sdate, \"AcctInputOctets\" ) / 1048576; my $output = $cust_pkg->attribute_since_sqlradacct($last_bill, $sdate, \"AcctOutputOctets\" ) / 1048576; my $total = $input + $output - \' + what.recur_included_total.value + \'; $total = 0 if $total < 0; my $input = $input - \' + what.recur_included_input.value + \'; $input = 0 if $input < 0; my $output = $output - \' + what.recur_included_output.value + \'; $output = 0 if $output < 0; my $totalcharge = sprintf(\"%.2f\", \' + what.recur_total_charge.value + \' * $total); my $hourscharge = sprintf(\"%.2f\", \' + what.recur_hourly_charge.value + \' * $hours); push @details, \"Last month\\\'s excess data \". sprintf(\"%.1f\", $total). \" megs: \\\$$totalcharge\", \"Last month\\\'s excess time \". sprintf(\"%.1f\", $hours). \" hours: \\\$$hourscharge\"; \' + what.recur_flat.value + \' + $hourscharge + \' + what.recur_input_charge.value + \' * $input + \' + what.recur_output_charge.value + \' * $output + $totalcharge ;\'', + }, + + 'sql_generic' => { + 'name' => 'Base charge plus a metered rate from a configurable SQL query', + 'fields' => { + 'setup_fee' => { 'name' => 'Setup fee for this package', + 'default' => 0, + }, + 'recur_flat' => { 'name' => 'Base monthly charge for this package', + 'default' => 0, + }, + 'recur_included' => { 'name' => 'Units included', + 'default' => 0, + }, + 'recur_unit_charge' => { 'name' => 'Additional charge per unit', + 'default' => 0, + }, + 'datasrc' => { 'name' => 'DBI data source', + 'default' => '', + }, + 'db_username' => { 'name' => 'Database username', + 'default' => '', + }, + 'db_password' => { 'name' => 'Database username', + 'default' => '', + }, + 'query' => { 'name' => 'SQL query', + 'default' => '', + }, + }, + 'fieldorder' => [qw( setup_fee recur_flat recur_included recur_unit_charge datasrc db_username db_password query )], + 'setup' => 'what.setup_fee.value', + # 'recur' => '\'my $dbh = DBI->connect(\"\' + what.datasrc.value + \'\", \"\' + what.db_username.value + \'\") or die $DBI::errstr; \'', + 'recur' => '\'my $dbh = DBI->connect(\"\' + what.datasrc.value + \'\", \"\' + what.db_username.value + \'\", \"\' + what.db_password.value + \'\" ) or die $DBI::errstr; my $sth = $dbh->prepare(\"\' + what.query.value + \'\") or die $dbh->errstr; my $units = 0; foreach my $cust_svc ( grep { $_->part_svc->svcdb eq \"svc_domain\" } $cust_pkg->cust_svc ) { my $domain = $cust_svc->svc_x->domain; $sth->execute($domain) or die $sth->errstr; $units += $sth->fetchrow_arrayref->[0]; } $units -= \' + what.recur_included.value + \'; $units = 0 if $units < 0; \' + what.recur_flat.value + \' + $units * \' + what.recur_unit_charge.value + \';\'', + #'recur' => '\'my $dbh = DBI->connect("\' + what.datasrc.value + \'", "\' + what.db_username.value + \'", "\' what.db_password.value + \'" ) or die $DBI::errstr; my $sth = $dbh->prepare("\' + what.query.value + \'") or die $dbh->errstr; my $units = 0; foreach my $cust_svc ( grep { $_->part_svc->svcdb eq "svc_domain" } $cust_pkg->cust_svc ) { my $domain = $cust_svc->svc_x->domain; $sth->execute($domain) or die $sth->errstr; $units += $sth->fetchrow_arrayref->[0]; } $units -= \' + what.recur_included.value + \'; $units = 0 if $units < 0; \' + what.recur_flat.value + \' + $units * \' + what.recur_unit_charge + \';\'', + }, + + + + 'sql_external' => { + 'name' => 'Base charge plus additional fees for external services from a configurable SQL query', + 'fields' => { + 'setup_fee' => { 'name' => 'Setup fee for this package', + 'default' => 0, + }, + 'recur_flat' => { 'name' => 'Base monthly charge for this package', + 'default' => 0, + }, + 'datasrc' => { 'name' => 'DBI data source', + 'default' => '', + }, + 'db_username' => { 'name' => 'Database username', + 'default' => '', + }, + 'db_password' => { 'name' => 'Database password', + 'default' => '', + }, + 'query' => { 'name' => 'SQL query', + 'default' => '', + }, + }, + 'fieldorder' => [qw( setup_fee recur_flat datasrc db_username db_password query )], + 'setup' => 'what.setup_fee.value', + 'recur' => q!'my $dbh = DBI->connect("' + what.datasrc.value + '", "' + what.db_username.value + '", "' + what.db_password.value + '" ) or die $DBI::errstr; my $sth = $dbh->prepare("' + what.query.value + '") or die $dbh->errstr; my $price = ' + what.recur_flat.value + '; foreach my $cust_svc ( grep { $_->part_svc->svcdb eq "svc_external" } $cust_pkg->cust_svc ){ my $id = $cust_svc->svc_x->id; $sth->execute($id) or die $sth->errstr; $price += $sth->fetchrow_arrayref->[0]; } $price;'!, + + }, + ; my %plandata = map { /^(\w+)=(.*)$/; ( $1 => $2 ); } @@ -369,6 +527,10 @@ if ( $conf->exists('enable_taxclasses') ) { push @fixups, 'taxclass'; #hidden } +my @form_radio = (); +if ( dbdef->table('pkg_svc')->column('primary_svc') ) { + push @form_radio, 'pkg_svc_primary'; +} my $widget = new HTML::Widgets::SelectLayers( 'selected_layer' => $part_pkg->plan, @@ -377,7 +539,8 @@ my $widget = new HTML::Widgets::SelectLayers( 'form_action' => 'process/part_pkg.cgi', 'form_text' => [ qw(pkg comment freq clone pkgnum pkgpart), @fixups ], 'form_checkbox' => [ qw(setuptax recurtax disabled) ], - 'form_select' => [ @form_select ], + 'form_radio' => \@form_radio, + 'form_select' => \@form_select, 'fixup_callback' => sub { #my $ = @_; my $html = ''; @@ -442,11 +605,11 @@ my $widget = new HTML::Widgets::SelectLayers( '<TR><TD>'. '<FONT SIZE="1">Setup expression<BR>'. '<INPUT TYPE="text" NAME="setup" SIZE="160" VALUE="'. - $hashref->{setup}. '" onLoad="fchanged(this)">'. + encode_entities($hashref->{setup}). '" onLoad="fchanged(this)">'. '</FONT><BR>'. '<FONT SIZE="1">Recurring espression<BR>'. '<INPUT TYPE="text" NAME="recur" SIZE="160" VALUE="'. - $hashref->{recur}. '" onLoad="fchanged(this)">'. + encode_entities($hashref->{recur}). '" onLoad="fchanged(this)">'. '</FONT>'. '</TR></TD>'. '</TABLE>'; diff --git a/httemplate/edit/part_svc.cgi b/httemplate/edit/part_svc.cgi index 4ccb770fb..6868ffd65 100755 --- a/httemplate/edit/part_svc.cgi +++ b/httemplate/edit/part_svc.cgi @@ -50,9 +50,10 @@ Disable new orders <INPUT TYPE="checkbox" NAME="disabled" VALUE="Y"<%= $hashref- Services are items you offer to your customers. <UL><LI>svc_acct - Shell accounts, POP mailboxes, SLIP/PPP and ISDN accounts <LI>svc_domain - Domains - <LI>svc_acct_sm - <B>deprecated</B> (use svc_forward for new installations) Virtual domain mail aliasing. <LI>svc_forward - mail forwarding <LI>svc_www - Virtual domain website + <LI>svc_broadband - Broadband/High-speed Internet service + <LI>svc_external - Externally-tracked service <!-- <LI>svc_charge - One-time charges (Partially unimplemented) <LI>svc_wo - Work orders (Partially unimplemented) --> @@ -65,6 +66,9 @@ blank <B>slipip</B> as well as a fixed shell something like <B>/bin/true</B> or <BR><BR> <% + +my %vfields; + #these might belong somewhere else for other user interfaces #pry need to eventually create stuff that's shared amount UIs my %defs = ( @@ -80,7 +84,10 @@ my %defs = ( select_key => 'popnum', select_label => 'city', }, - 'username' => 'Username', + 'username' => { + desc => 'Username', + type => 'disabled', + }, 'quota' => '', '_password' => 'Password', 'gid' => 'GID (when blank, defaults to UID)', @@ -101,34 +108,57 @@ my %defs = ( 'svc_domain' => { 'domain' => 'Domain', }, - 'svc_acct_sm' => { - 'domuser' => 'domuser@virtualdomain.com', - 'domuid' => 'UID where domuser@virtualdomain.com mail is forwarded', - 'domsvc' => 'svcnum from svc_domain for virtualdomain.com', - }, 'svc_forward' => { 'srcsvc' => 'service from which mail is to be forwarded', 'dstsvc' => 'service to which mail is to be forwarded', 'dst' => 'someone@another.domain.com to use when dstsvc is 0', }, - 'svc_charge' => { - 'amount' => 'amount', - }, - 'svc_wo' => { - 'worker' => 'Worker', - '_date' => 'Date', - }, +# 'svc_charge' => { +# 'amount' => 'amount', +# }, +# 'svc_wo' => { +# 'worker' => 'Worker', +# '_date' => 'Date', +# }, 'svc_www' => { #'recnum' => '', #'usersvc' => '', }, + 'svc_broadband' => { + 'speed_down' => 'Maximum download speed for this service in Kbps. 0 denotes unlimited.', + 'speed_up' => 'Maximum upload speed for this service in Kbps. 0 denotes unlimited.', + 'ip_addr' => 'IP address. Leave blank for automatic assignment.', + 'blocknum' => 'Address block.', + }, + 'svc_external' => { + #'id' => '', + #'title' => '', + }, ); + foreach my $svcdb (grep dbdef->table($_), keys %defs ) { + my $self = "FS::$svcdb"->new; + $vfields{$svcdb} = {}; + foreach my $field ($self->virtual_fields) { # svc_Common::virtual_fields with a null svcpart returns all of them + my $pvf = $self->pvf($field); + my @list = $pvf->list; + if (scalar @list) { + $defs{$svcdb}->{$field} = { desc => $pvf->label, + type => 'select', + select_list => \@list }; + } else { + $defs{$svcdb}->{$field} = $pvf->label; + } #endif + $vfields{$svcdb}->{$field} = $pvf; + warn "\$vfields{$svcdb}->{$field} = $pvf"; + } #next $field + } #next $svcdb + my @dbs = $hashref->{svcdb} ? ( $hashref->{svcdb} ) - : qw( svc_acct svc_domain svc_acct_sm svc_forward svc_www ); + : qw( svc_acct svc_domain svc_forward svc_www svc_broadband svc_external ); - tie my %svcdb, 'Tie::IxHash', map { $_=>$_ } @dbs; + tie my %svcdb, 'Tie::IxHash', map { $_=>$_ } grep dbdef->table($_), @dbs; my $widget = new HTML::Widgets::SelectLayers( #'selected_layer' => $p_svcdb, 'selected_layer' => $hashref->{svcdb} || 'svc_acct', @@ -146,17 +176,18 @@ my %defs = ( my @part_export = map { qsearch( 'part_export', {exporttype => $_ } ) } keys %{FS::part_export::export_info($layer)}; - $html .= '<BR><BR>'. table(). + $html .= '<BR><BR>'. table(). table(). "<TR><TH COLSPAN=$columns>Exports</TH></TR><TR>"; foreach my $part_export ( @part_export ) { $html .= '<TD><INPUT TYPE="checkbox"'. ' NAME="exportnum'. $part_export->exportnum. '" VALUE="1" '; $html .= 'CHECKED' - if qsearchs( 'export_svc', { + if ( $clone || $part_svc->svcpart ) #null svcpart search causing error + && qsearchs( 'export_svc', { exportnum => $part_export->exportnum, svcpart => $clone || $part_svc->svcpart }); - $html .= '> '. $part_export->exporttype. ' to '. $part_export->machine. - '</TD>'; + $html .= '>'. $part_export->exportnum. ': '. $part_export->exporttype. + ' to '. $part_export->machine. '</TD>'; $count++; $html .= '</TR><TR>' unless $count % $columns; } @@ -183,28 +214,44 @@ my %defs = ( $html .= "<TR><TD>$field"; $html .= "- <FONT SIZE=-1>$desc</FONT>" if $desc; $html .= "</TD>"; + $flag = '' if ref($def) && $def->{type} eq 'disabled'; $html .= qq!<TD><INPUT TYPE="radio" NAME="${layer}__${field}_flag" VALUE=""!. ' CHECKED'x($flag eq ''). ">Off</TD>". - qq!<TD><INPUT TYPE="radio" NAME="${layer}__${field}_flag" VALUE="D"!. - ' CHECKED'x($flag eq 'D'). ">Default ". - qq!<INPUT TYPE="radio" NAME="${layer}__${field}_flag" VALUE="F"!. - ' CHECKED'x($flag eq 'F'). ">Fixed ". - '<BR>'; + '<TD>'; + unless ( ref($def) && $def->{type} eq 'disabled' ) { + $html .= + qq!<INPUT TYPE="radio" NAME="${layer}__${field}_flag" VALUE="D"!. + ' CHECKED'x($flag eq 'D'). ">Default ". + qq!<INPUT TYPE="radio" NAME="${layer}__${field}_flag" VALUE="F"!. + ' CHECKED'x($flag eq 'F'). ">Fixed "; + $html .= '<BR>'; + } if ( ref($def) ) { if ( $def->{type} eq 'select' ) { $html .= qq!<SELECT NAME="${layer}__${field}">!; $html .= '<OPTION> </OPTION>' unless $value; - foreach my $record ( qsearch( $def->{select_table}, {} ) ) { - my $rvalue = $record->getfield($def->{select_key}); - $html .= qq!<OPTION VALUE="$rvalue"!. - ( $rvalue==$value ? ' SELECTED>' : '>' ). - $record->getfield($def->{select_label}). '</OPTION>'; - } + if ( $def->{select_table} ) { + foreach my $record ( qsearch( $def->{select_table}, {} ) ) { + my $rvalue = $record->getfield($def->{select_key}); + $html .= qq!<OPTION VALUE="$rvalue"!. + ( $rvalue==$value ? ' SELECTED>' : '>' ). + $record->getfield($def->{select_label}). '</OPTION>'; + } #next $record + } else { # select_list + foreach my $item ( @{$def->{select_list}} ) { + $html .= qq!<OPTION VALUE="$item"!. + ( $item eq $value ? ' SELECTED>' : '>' ). + $item. '</OPTION>'; + } #next $item + } #endif $html .= '</SELECT>'; } elsif ( $def->{type} eq 'radius_usergroup_selector' ) { $html .= FS::svc_acct::radius_usergroup_selector( [ split(',', $value) ], "${layer}__${field}" ); + } elsif ( $def->{type} eq 'disabled' ) { + $html .= + qq!<INPUT TYPE="hidden" NAME="${layer}__${field}" VALUE="">!; } else { $html .= '<font color="#ff0000">unknown type'. $def->{type}; } @@ -212,6 +259,11 @@ my %defs = ( $html .= qq!<INPUT TYPE="text" NAME="${layer}__${field}" VALUE="$value">!; } + + if($vfields{$layer}->{$field}) { + $html .= qq!<BR><INPUT TYPE="radio" NAME="${layer}__${field}_flag" VALUE="X"!. + ' CHECKED'x($flag eq 'X'). ">Excluded "; + } $html .= "</TD></TR>\n"; } $part_svc->svcpart('') if $clone; #undone diff --git a/httemplate/edit/part_virtual_field.cgi b/httemplate/edit/part_virtual_field.cgi new file mode 100644 index 000000000..8bc84387f --- /dev/null +++ b/httemplate/edit/part_virtual_field.cgi @@ -0,0 +1,92 @@ +<!-- mason kludge --> +<% +my ($vfieldpart, $part_virtual_field); + +if ( $cgi->param('error') ) { + $part_virtual_field = new FS::part_virtual_field ( { + map { $_, scalar($cgi->param($_)) } fields('part_virtual_field')}); + $vfieldpart = $part_virtual_field->vfieldpart; +} else { + my($query) = $cgi->keywords; + if ( $query =~ /^(\d+)$/ ) { #editing + $vfieldpart=$1; + $part_virtual_field=qsearchs('part_virtual_field', + {'vfieldpart' => $vfieldpart}) + or die "Unknown vfieldpart!"; + + } else { #adding + $part_virtual_field = new FS::part_virtual_field({}); + } +} +my $action = $part_virtual_field->vfieldpart ? 'Edit' : 'Add'; + +my $p1 = popurl(1); +print header("$action Virtual Field Definition", ''); + +print qq!<FONT SIZE="+1" COLOR="#ff0000">Error: !, $cgi->param('error'), + "</FONT>" + if $cgi->param('error'); +%> +<FORM ACTION="<%=$p1%>process/generic.cgi" METHOD="POST"> + +<INPUT TYPE="hidden" NAME="table" VALUE="part_virtual_field"> +<INPUT TYPE="hidden" NAME="redirect_ok" + VALUE="<%=popurl(2)%>browse/part_virtual_field.cgi"> +<INPUT TYPE="hidden" NAME="vfieldpart" VALUE="<%= + $vfieldpart%>"> +Field #<B><%=$vfieldpart or "(NEW)"%></B><BR><BR> + +<%=ntable("#cccccc",2)%> + <TR> + <TD ALIGN="right">Name</TD> + <TD><INPUT TYPE="text" NAME="name" MAXLENGTH=15 VALUE="<%= + $part_virtual_field->name%>"></TD> + </TR> + <TR> + <TD ALIGN="right">Table</TD> + <TD><% if ($action eq 'Add') { %> + <SELECT SIZE=1 NAME="dbtable"><% + my $dbdef = dbdef; # ick + foreach my $dbtable ($dbdef->tables) { + if ($dbtable !~ /^h_/ + and $dbdef->table($dbtable)->primary_key) { %> + <OPTION VALUE="<%=$dbtable%>"><%=$dbtable%></OPTION><% + } + } + %></SELECT><% + } else { # Edit + %><%=$part_virtual_field->dbtable%> + <INPUT TYPE="hidden" NAME="dbtable" VALUE="<%=$part_virtual_field->dbtable%>"> + <% } %> + </TD> + <TR> + <TD ALIGN="right">Label</TD> + <TD><INPUT TYPE="text" NAME="label" MAXLENGTH="20" VALUE="<%= + $part_virtual_field->label%>"></TD> + </TR> + <TR> + <TD ALIGN="right">Length</TD> + <TD><INPUT TYPE="text" NAME="length" MAXLENGTH=4 VALUE="<%= + $part_virtual_field->length%>"></TD> + </TR> + <TR> + <TD ALIGN="right">Check</TD> + <TD><TEXTAREA COLS="20" ROWS="4" NAME="check_block"><%= + $part_virtual_field->check_block%></TEXTAREA></TD> + </TR> + <TR> + <TD ALIGN="right">List source</TD> + <TD><TEXTAREA COLS="20" ROWS="4" NAME="list_source"><%= + $part_virtual_field->list_source%></TEXTAREA></TD> + </TR> +</TABLE><BR><INPUT TYPE="submit" VALUE="Submit"> + +</FORM> + +<BR><BR> +<FONT SIZE=-2>If you don't understand what <I>check_block</I> and +<I>list_source</I> mean, <B>LEAVE THEM BLANK</B>. We mean it.</FONT> + + +</BODY> +</HTML> diff --git a/httemplate/edit/process/REAL_cust_pkg.cgi b/httemplate/edit/process/REAL_cust_pkg.cgi index 2e0352c76..7f5c5e49c 100755 --- a/httemplate/edit/process/REAL_cust_pkg.cgi +++ b/httemplate/edit/process/REAL_cust_pkg.cgi @@ -5,6 +5,8 @@ my $old = qsearchs('cust_pkg',{'pkgnum'=>$pkgnum}); my %hash = $old->hash; $hash{'setup'} = $cgi->param('setup') ? str2time($cgi->param('setup')) : ''; $hash{'bill'} = $cgi->param('bill') ? str2time($cgi->param('bill')) : ''; +$hash{'last_bill'} = + $cgi->param('last_bill') ? str2time($cgi->param('last_bill')) : ''; $hash{'expire'} = $cgi->param('expire') ? str2time($cgi->param('expire')) : ''; my $new = new FS::cust_pkg \%hash; diff --git a/httemplate/edit/process/addr_block/add.cgi b/httemplate/edit/process/addr_block/add.cgi new file mode 100755 index 000000000..34d799ccd --- /dev/null +++ b/httemplate/edit/process/addr_block/add.cgi @@ -0,0 +1,20 @@ +<% + +my $error = ''; +my $ip_gateway = $cgi->param('ip_gateway'); +my $ip_netmask = $cgi->param('ip_netmask'); + +my $new = new FS::addr_block { + ip_gateway => $ip_gateway, + ip_netmask => $ip_netmask, + routernum => 0 }; + +$error = $new->insert; + +if ( $error ) { + $cgi->param('error', $error); + print $cgi->redirect(popurl(4). "browse/addr_block.cgi?". $cgi->query_string ); +} else { + print $cgi->redirect(popurl(4). "browse/addr_block.cgi"); +} +%> diff --git a/httemplate/edit/process/addr_block/allocate.cgi b/httemplate/edit/process/addr_block/allocate.cgi new file mode 100755 index 000000000..85b0d7a7a --- /dev/null +++ b/httemplate/edit/process/addr_block/allocate.cgi @@ -0,0 +1,25 @@ +<% +my $error = ''; +my $blocknum = $cgi->param('blocknum'); +my $routernum = $cgi->param('routernum'); + +my $addr_block = qsearchs('addr_block', { blocknum => $blocknum }); +my $router = qsearchs('router', { routernum => $routernum }); + +if($addr_block) { + if ($router) { + $error = $addr_block->allocate($router); + } else { + $error = "Cannot find router with routernum $routernum"; + } +} else { + $error = "Cannot find block with blocknum $blocknum"; +} + +if ( $error ) { + $cgi->param('error', $error); + print $cgi->redirect(popurl(4). "browse/addr_block.cgi?" . $cgi->query_string); +} else { + print $cgi->redirect(popurl(4). "browse/addr_block.cgi"); +} +%> diff --git a/httemplate/edit/process/addr_block/deallocate.cgi b/httemplate/edit/process/addr_block/deallocate.cgi new file mode 100755 index 000000000..cfb7ed04d --- /dev/null +++ b/httemplate/edit/process/addr_block/deallocate.cgi @@ -0,0 +1,24 @@ +<% +my $error = ''; +my $blocknum = $cgi->param('blocknum'); + +my $addr_block = qsearchs('addr_block', { blocknum => $blocknum }); + +if($addr_block) { + my $router = $addr_block->router; + if ($router) { + $error = $addr_block->deallocate($router); + } else { + $error = "Block is not allocated to a router"; + } +} else { + $error = "Cannot find block with blocknum $blocknum"; +} + +if ( $error ) { + $cgi->param('error', $error); + print $cgi->redirect(popurl(4). "browse/addr_block.cgi?" . $cgi->query_string); +} else { + print $cgi->redirect(popurl(4). "browse/addr_block.cgi"); +} +%> diff --git a/httemplate/edit/process/addr_block/split.cgi b/httemplate/edit/process/addr_block/split.cgi new file mode 100755 index 000000000..bb6d4ba3e --- /dev/null +++ b/httemplate/edit/process/addr_block/split.cgi @@ -0,0 +1,19 @@ +<% +my $error = ''; +my $blocknum = $cgi->param('blocknum'); +my $addr_block = qsearchs('addr_block', { blocknum => $blocknum }); + +if ( $addr_block) { + $error = $addr_block->split_block; +} else { + $error = "Unknown blocknum: $blocknum"; +} + + +if ( $error ) { + $cgi->param('error', $error); + print $cgi->redirect(popurl(4). "browse/addr_block.cgi?". $cgi->query_string ); +} else { + print $cgi->redirect(popurl(4). "browse/addr_block.cgi"); +} +%> diff --git a/httemplate/edit/process/cust_main.cgi b/httemplate/edit/process/cust_main.cgi index 6ce60d14a..25c346e46 100755 --- a/httemplate/edit/process/cust_main.cgi +++ b/httemplate/edit/process/cust_main.cgi @@ -10,16 +10,25 @@ $cgi->param('refnum', (split(/:/, ($cgi->param('refnum'))[0] ))[0] ); my $payby = $cgi->param('payby'); if ( $payby ) { - $cgi->param('payinfo', $cgi->param( $payby. '_payinfo' ) ); + if ( $payby eq 'CHEK' || $payby eq 'DCHK' ) { + $cgi->param('payinfo', + $cgi->param($payby. '_payinfo1'). '@'. $cgi->param($payby. '_payinfo2') ); + } else { + $cgi->param('payinfo', $cgi->param( $payby. '_payinfo' ) ); + } $cgi->param('paydate', - $cgi->param( $payby. '_month' ). '-'. $cgi->param( $payby. '_year' ) ); + $cgi->param( $payby. '_month' ). '-'. $cgi->param( $payby. '_year' ) ); $cgi->param('payname', $cgi->param( $payby. '_payname' ) ); + $cgi->param('paycvv', $cgi->param( $payby. '_paycvv' ) ) + if defined $cgi->param( $payby. '_paycvv' ); } $cgi->param('otaker', &getotaker ); my @invoicing_list = split( /\s*\,\s*/, $cgi->param('invoicing_list') ); push @invoicing_list, 'POST' if $cgi->param('invoicing_list_POST'); +$cgi->param('invoicing_list', join(',', @invoicing_list) ); + #create new record object @@ -46,7 +55,7 @@ if ( $new->custnum eq '' ) { if ( $cgi->param('pkgpart_svcpart') ) { my $x = $cgi->param('pkgpart_svcpart'); - $x =~ /^(\d+)_(\d+)$/; + $x =~ /^(\d+)_(\d+)$/ or die "illegal pkgpart_svcpart $x\n"; my($pkgpart, $svcpart) = ($1, $2); #false laziness: copied from FS::cust_pkg::order (which should become a #FS::cust_main method) @@ -64,7 +73,7 @@ if ( $new->custnum eq '' ) { #eslaf # this should wind up in FS::cust_pkg! - $error ||= "Agent ". $new->agentnum. " (type ". $agent->typenum. ") can't". + $error ||= "Agent ". $new->agentnum. " (type ". $agent->typenum. ") can't ". "purchase pkgpart ". $pkgpart #unless $part_pkg{ $pkgpart }; unless $pkgpart_href->{ $pkgpart }; @@ -107,6 +116,11 @@ if ( $new->custnum eq '' ) { } else { #create old record object my $old = qsearchs( 'cust_main', { 'custnum' => $new->custnum } ); $error ||= "Old record not found!" unless $old; + if ( defined dbdef->table('cust_main')->column('paycvv') + && length($old->paycvv) + && $new->paycvv =~ /^\s*\*+\s*$/ ) { + $new->paycvv($old->paycvv); + } $error ||= $new->replace($old, \@invoicing_list); } diff --git a/httemplate/edit/process/cust_main_county-collapse.cgi b/httemplate/edit/process/cust_main_county-collapse.cgi index 8e67140a8..5da9dea80 100755 --- a/httemplate/edit/process/cust_main_county-collapse.cgi +++ b/httemplate/edit/process/cust_main_county-collapse.cgi @@ -3,8 +3,8 @@ my($query) = $cgi->keywords; $query =~ /^(\d+)$/ or die "Illegal taxnum!"; my $taxnum = $1; -my $cust_main_county = qsearchs('cust_main_county',{'taxnum'=>$taxnum}) - or die ("Unknown taxnum!"); +my $cust_main_county = qsearchs('cust_main_county', { 'taxnum' => $taxnum } ) + or die "Unknown taxnum $taxnum"; #really should do this in a .pm & start transaction diff --git a/httemplate/edit/process/cust_main_county.cgi b/httemplate/edit/process/cust_main_county.cgi index 990a23919..9287ed150 100755 --- a/httemplate/edit/process/cust_main_county.cgi +++ b/httemplate/edit/process/cust_main_county.cgi @@ -2,17 +2,22 @@ foreach ( grep { /^tax\d+$/ } $cgi->param ) { /^tax(\d+)$/ or die "Illegal form $_!"; - my($taxnum)=$1; - my($old)=qsearchs('cust_main_county',{'taxnum'=>$taxnum}) + my $taxnum = $1; + my $old = qsearchs('cust_main_county', { 'taxnum' => $taxnum }) or die "Couldn't find taxnum $taxnum!"; - my $exempt_amount = $cgi->param("exempt_amount$taxnum"); - next unless $old->tax ne $cgi->param("tax$taxnum") - || $old->exempt_amount ne $exempt_amount; + next unless $old->tax != $cgi->param("tax$taxnum") + || $old->exempt_amount != $cgi->param("exempt_amount$taxnum") + || $old->taxname ne $cgi->param("taxname$taxnum") + || $old->setuptax ne $cgi->param("setuptax$taxnum") + || $old->recurtax ne $cgi->param("recurtax$taxnum"); my %hash = $old->hash; $hash{tax} = $cgi->param("tax$taxnum"); - $hash{exempt_amount} = $exempt_amount; - my($new)=new FS::cust_main_county \%hash; - my($error)=$new->replace($old); + $hash{exempt_amount} = $cgi->param("exempt_amount$taxnum"); + $hash{taxname} = $cgi->param("taxname$taxnum"); + $hash{setuptax} = $cgi->param("setuptax$taxnum"); + $hash{recurtax} = $cgi->param("recurtax$taxnum"); + my $new = new FS::cust_main_county \%hash; + my $error = $new->replace($old); if ( $error ) { $cgi->param('error', $error); print $cgi->redirect(popurl(2). "cust_main_county.cgi?". $cgi->query_string ); diff --git a/httemplate/edit/process/cust_pkg.cgi b/httemplate/edit/process/cust_pkg.cgi index f8c9f5151..df8471c27 100755 --- a/httemplate/edit/process/cust_pkg.cgi +++ b/httemplate/edit/process/cust_pkg.cgi @@ -11,16 +11,23 @@ my @remove_pkgnums = map { $1; } $cgi->param('remove_pkg'); +my $error_redirect; my @pkgparts; -foreach my $pkgpart ( map /^pkg(\d+)$/ ? $1 : (), $cgi->param ) { - if ( $cgi->param("pkg$pkgpart") =~ /^(\d+)$/ ) { - my $num_pkgs = $1; - while ( $num_pkgs-- ) { - push @pkgparts,$pkgpart; +if ( $cgi->param('new_pkgpart') =~ /^(\d+)$/ ) { #came from misc/change_pkg.cgi + $error_redirect = "misc/change_pkg.cgi"; + @pkgparts = ($1); +} else { #came from edit/cust_pkg.cgi + $error_redirect = "edit/cust_pkg.cgi"; + foreach my $pkgpart ( map /^pkg(\d+)$/ ? $1 : (), $cgi->param ) { + if ( $cgi->param("pkg$pkgpart") =~ /^(\d+)$/ ) { + my $num_pkgs = $1; + while ( $num_pkgs-- ) { + push @pkgparts,$pkgpart; + } + } else { + $error = "Illegal quantity"; + last; } - } else { - $error = "Illegal quantity"; - last; } } @@ -28,7 +35,7 @@ $error ||= FS::cust_pkg::order($custnum,\@pkgparts,\@remove_pkgnums); if ($error) { $cgi->param('error', $error); - print $cgi->redirect(popurl(2). "cust_pkg.cgi?". $cgi->query_string ); + print $cgi->redirect(popurl(3). $error_redirect. '?'. $cgi->query_string ); } else { print $cgi->redirect(popurl(3). "view/cust_main.cgi?$custnum"); } diff --git a/httemplate/edit/process/generic.cgi b/httemplate/edit/process/generic.cgi new file mode 100644 index 000000000..9c54feb1d --- /dev/null +++ b/httemplate/edit/process/generic.cgi @@ -0,0 +1,70 @@ +<% + +# Welcome to generic.cgi. +# +# This script provides a generic edit/process/ backend for simple table +# editing. All it knows how to do is take the values entered into +# the script and insert them into the table specified by $cgi->param('table'). +# If there's an existing record with the same primary key, it will be +# replaced. (Deletion will be added in the future.) +# +# Special cgi params for this script: +# table: the name of the table to be edited. The script will die horribly +# if it can't find the table. +# redirect_ok: URL to be displayed after a successful edit. The value of +# the record's primary key will be passed as a keyword. +# Defaults to (freeside root)/view/$table.cgi. +# redirect_error: URL to be displayed if there's an error. The original +# query string, plus the error message, will be passed. +# Defaults to $cgi->referer() (i.e. go back where you +# came from). + + +use FS::Record qw(qsearchs dbdef); +use DBIx::DBSchema; +use DBIx::DBSchema::Table; + + +my $error; +my $p2 = popurl(2); +my $p3 = popurl(3); +my $table = $cgi->param('table'); +my $dbdef = dbdef or die "Cannot fetch dbdef!"; + +my $dbdef_table = $dbdef->table($table) or die "Cannot fetch schema for $table"; + +my $pkey = $dbdef_table->primary_key or die "Cannot fetch pkey for $table"; +my $pkey_val = $cgi->param($pkey); + + +#warn "new FS::Record ( $table, (hashref) )"; +my $new = FS::Record::new ( "FS::$table", { + map { $_, scalar($cgi->param($_)) } fields($table) +} ); + +#warn 'created $new of class '.ref($new); + +if($pkey_val and (my $old = qsearchs($table, { $pkey, $pkey_val} ))) { + # edit + $error = $new->replace($old); +} else { + #add + $error = $new->insert; + $pkey_val = $new->getfield($pkey); + # New records usually don't have their primary keys set until after + # they've been checked/inserted, so grab the new $pkey_val so we can + # redirect to it. +} + +my $redirect_ok = (($cgi->param('redirect_ok')) ? + $cgi->param('redirect_ok') : $p3."browse/generic.cgi?$table"); +my $redirect_error = (($cgi->param('redirect_error')) ? + $cgi->param('redirect_error') : $cgi->referer()); + +if($error) { + $cgi->param('error', $error); + print $cgi->redirect($redirect_error . '?' . $cgi->query_string); +} else { + print $cgi->redirect($redirect_ok); +} +%> diff --git a/httemplate/edit/process/part_bill_event.cgi b/httemplate/edit/process/part_bill_event.cgi index 4049ade80..e224bf634 100755 --- a/httemplate/edit/process/part_bill_event.cgi +++ b/httemplate/edit/process/part_bill_event.cgi @@ -12,7 +12,7 @@ if ( ! $cgi->param('plan_weight_eventcode') ) { $error = "Must select an action"; } else { - $cgi->param('plan_weight_eventcode') =~ /^([\w\-]+):(\d+):(.*)$/ + $cgi->param('plan_weight_eventcode') =~ /^([\w\-]+):(\d+):(.*)$/s or die "illegal plan_weight_eventcode:". $cgi->param('plan_weight_eventcode'); $cgi->param('plan', $1); diff --git a/httemplate/edit/process/part_pkg.cgi b/httemplate/edit/process/part_pkg.cgi index d489426f9..7eada7bc8 100755 --- a/httemplate/edit/process/part_pkg.cgi +++ b/httemplate/edit/process/part_pkg.cgi @@ -62,16 +62,24 @@ if ( $error ) { foreach my $part_svc (qsearch('part_svc',{})) { my $quantity = $cgi->param('pkg_svc'. $part_svc->svcpart) || 0; + my $primary_svc = + $cgi->param('pkg_svc_primary') == $part_svc->svcpart ? 'Y' : ''; my $old_pkg_svc = qsearchs('pkg_svc', { 'pkgpart' => $pkgpart, 'svcpart' => $part_svc->svcpart, } ); my $old_quantity = $old_pkg_svc ? $old_pkg_svc->quantity : 0; - next unless $old_quantity != $quantity; #!here + my $old_primary_svc = + ( $old_pkg_svc && $old_pkg_svc->dbdef_table->column('primary_svc') ) + ? $old_pkg_svc->primary_svc + : ''; + next unless $old_quantity != $quantity || $old_primary_svc ne $primary_svc; + my $new_pkg_svc = new FS::pkg_svc( { - 'pkgpart' => $pkgpart, - 'svcpart' => $part_svc->svcpart, - 'quantity' => $quantity, + 'pkgpart' => $pkgpart, + 'svcpart' => $part_svc->svcpart, + 'quantity' => $quantity, + 'primary_svc' => $primary_svc, } ); if ( $old_pkg_svc ) { my $myerror = $new_pkg_svc->replace($old_pkg_svc); diff --git a/httemplate/edit/process/part_svc.cgi b/httemplate/edit/process/part_svc.cgi index 859670b17..9633fabdf 100755 --- a/httemplate/edit/process/part_svc.cgi +++ b/httemplate/edit/process/part_svc.cgi @@ -17,7 +17,7 @@ my $new = new FS::part_svc ( { push @fields, 'usergroup' if $svcdb eq 'svc_acct'; #kludge map { ( $svcdb.'__'.$_, $svcdb.'__'.$_.'_flag' ) } @fields; } grep defined( $FS::Record::dbdef->table($_) ), - qw( svc_acct svc_domain svc_acct_sm svc_forward svc_www ) + qw( svc_acct svc_domain svc_forward svc_www svc_broadband ) ) } ); diff --git a/httemplate/edit/process/router.cgi b/httemplate/edit/process/router.cgi new file mode 100644 index 000000000..a2fa46dd9 --- /dev/null +++ b/httemplate/edit/process/router.cgi @@ -0,0 +1,67 @@ +<% + +local $FS::UID::AutoCommit=0; + +sub check { + my $error = shift; + if($error) { + $cgi->param('error', $error); + print $cgi->redirect(popurl(3) . "edit/router.cgi?". $cgi->query_string); + dbh->rollback; + exit; + } +} + +my $error = ''; +my $routernum = $cgi->param('routernum'); +my $routername = $cgi->param('routername'); +my $old = qsearchs('router', { routernum => $routernum }); +my @old_psr; + +my $new = new FS::router { + map { + ($_, scalar($cgi->param($_))); + } fields('router') +}; + +if($old) { + $error = $new->replace($old); +} else { + $error = $new->insert; + $routernum = $new->routernum; +} + +check($error); + +if ($old) { + @old_psr = $old->part_svc_router; + foreach my $psr (@old_psr) { + if($cgi->param('svcpart_'.$psr->svcpart) eq 'ON') { + # do nothing + } else { + $error = $psr->delete; + } + } + check($error); +} + +foreach($cgi->param) { + if($cgi->param($_) eq 'ON' and /^svcpart_(\d+)$/) { + my $svcpart = $1; + if(grep {$_->svcpart == $svcpart} @old_psr) { + # do nothing + } else { + my $new_psr = new FS::part_svc_router { svcpart => $svcpart, + routernum => $routernum }; + $error = $new_psr->insert; + } + check($error); + } +} + + +# Yay, everything worked! +dbh->commit or die dbh->errstr; +print $cgi->redirect(popurl(3). "browse/router.cgi"); + +%> diff --git a/httemplate/edit/process/svc_acct_sm.cgi b/httemplate/edit/process/svc_acct_sm.cgi deleted file mode 100755 index 41d03fb92..000000000 --- a/httemplate/edit/process/svc_acct_sm.cgi +++ /dev/null @@ -1,34 +0,0 @@ -<% - -$cgi->param('svcnum') =~ /^(\d*)$/ or die "Illegal svcnum!"; -my $svcnum =$1; - -my $old = qsearchs('svc_acct_sm',{'svcnum'=>$svcnum}) if $svcnum; - -#unmunge domsvc and domuid -#$cgi->param('domsvc',(split(/:/, $cgi->param('domsvc') ))[0] ); -#$cgi->param('domuid',(split(/:/, $cgi->param('domuid') ))[0] ); - -my $new = new FS::svc_acct_sm ( { - map { - ($_, scalar($cgi->param($_))); - #} qw(svcnum pkgnum svcpart domuser domuid domsvc) - } ( fields('svc_acct_sm'), qw( pkgnum svcpart ) ) -} ); - -my $error = ''; -if ( $svcnum ) { - $error = $new->replace($old); -} else { - $error = $new->insert; - $svcnum = $new->getfield('svcnum'); -} - -if ($error) { - $cgi->param('error', $error); - print $cgi->redirect(popurl(2). "svc_acct_sm.cgi?". $cgi->query_string ); -} else { - print $cgi->redirect(popurl(3). "view/svc_acct_sm.cgi?$svcnum"); -} - -%> diff --git a/httemplate/edit/process/svc_broadband.cgi b/httemplate/edit/process/svc_broadband.cgi new file mode 100644 index 000000000..4912a3a9f --- /dev/null +++ b/httemplate/edit/process/svc_broadband.cgi @@ -0,0 +1,45 @@ +<% + +# If it's stupid but it works, it's not stupid. +# -- U.S. Army + +local $FS::UID::AutoCommit = 0; +my $dbh = FS::UID::dbh; + +$cgi->param('svcnum') =~ /^(\d*)$/ or die "Illegal svcnum!"; +my $svcnum = $1; + +my $old; +if ( $svcnum ) { + $old = qsearchs('svc_broadband', { 'svcnum' => $svcnum } ) + or die "fatal: can't find broadband service (svcnum $svcnum)!"; +} else { + $old = ''; +} + +my $new = new FS::svc_broadband ( { + map { + ($_, scalar($cgi->param($_))); + } ( fields('svc_broadband'), qw( pkgnum svcpart ) ) +} ); + +my $error; +if ( $svcnum ) { + $error = $new->replace($old); +} else { + $error = $new->insert; + $svcnum = $new->svcnum; +} + + +if ( $error ) { + $cgi->param('error', $error); + $cgi->param('ip_addr', $new->ip_addr); + $dbh->rollback; + print $cgi->redirect(popurl(2). "svc_broadband.cgi?". $cgi->query_string ); +} else { + $dbh->commit or die $dbh->errstr; + print $cgi->redirect(popurl(3). "view/svc_broadband.cgi?" . $svcnum ); +} + +%> diff --git a/httemplate/edit/process/svc_external.cgi b/httemplate/edit/process/svc_external.cgi new file mode 100755 index 000000000..728cd2189 --- /dev/null +++ b/httemplate/edit/process/svc_external.cgi @@ -0,0 +1,29 @@ +<% + +$cgi->param('svcnum') =~ /^(\d*)$/ or die "Illegal svcnum!"; +my $svcnum =$1; + +my $old = qsearchs('svc_external',{'svcnum'=>$svcnum}) if $svcnum; + +my $new = new FS::svc_external ( { + map { + ($_, scalar($cgi->param($_))); + } ( fields('svc_external'), qw( pkgnum svcpart ) ) +} ); + +my $error = ''; +if ( $svcnum ) { + $error = $new->replace($old); +} else { + $error = $new->insert; + $svcnum = $new->getfield('svcnum'); +} + +if ($error) { + $cgi->param('error', $error); + print $cgi->redirect(popurl(2). "svc_external.cgi?". $cgi->query_string ); +} else { + print $cgi->redirect(popurl(3). "view/svc_external.cgi?$svcnum"); +} + +%> diff --git a/httemplate/edit/router.cgi b/httemplate/edit/router.cgi new file mode 100755 index 000000000..a573c6504 --- /dev/null +++ b/httemplate/edit/router.cgi @@ -0,0 +1,77 @@ +<HTML><BODY> + +<% + +my $router; +if ( $cgi->keywords ) { + my($query) = $cgi->keywords; + $query =~ /^(\d+)$/; + $router = qsearchs('router', { routernum => $1 }) + or print $cgi->redirect(popurl(2)."browse/router.cgi") ; +} else { + $router = new FS::router ( { + map { $_, scalar($cgi->param($_)) } fields('router') + } ); +} + +my $routernum = $router->routernum; +my $action = $routernum ? 'Edit' : 'Add'; + +print header("$action Router", menubar( + 'Main Menu' => "$p", + 'View all routers' => "${p}browse/router.cgi", +)); + +my $p3 = popurl(3); + +if($cgi->param('error')) { +%> <FONT SIZE="+1" COLOR="#ff0000">Error: <%=$cgi->param('error')%></FONT> +<% } %> + +<FORM ACTION="<%=popurl(1)%>process/router.cgi" METHOD=POST> + <INPUT TYPE="hidden" NAME="table" VALUE="router"> + <INPUT TYPE="hidden" NAME="redirect_ok" VALUE="<%=$p3%>/browse/router.cgi"> + <INPUT TYPE="hidden" NAME="redirect_error" VALUE="<%=$p3%>/edit/router.cgi"> + <INPUT TYPE="hidden" NAME="routernum" VALUE="<%=$routernum%>"> + <INPUT TYPE="hidden" NAME="svcnum" VALUE="<%=$router->svcnum%>"> + Router #<%=$routernum or "(NEW)"%> + +<BR><BR>Name <INPUT TYPE="text" NAME="routername" SIZE=32 VALUE="<%=$router->routername%>"> + +<BR><BR> +Custom fields: +<BR> +<%=table() %> + +<% +foreach my $field ($router->virtual_fields) { + print $router->pvf($field)->widget('HTML', 'edit', + $router->getfield($field)); +} +%> +</TABLE> + + +<% +unless ($router->svcnum) { +%> +<BR><BR>Select the service types available on this router<BR> +<% + + foreach my $part_svc ( qsearch('part_svc', { svcdb => 'svc_broadband', + disabled => '' }) ) { + %> + <BR> + <INPUT TYPE="checkbox" NAME="svcpart_<%=$part_svc->svcpart%>"<%= + qsearchs('part_svc_router', { svcpart => $part_svc->svcpart, + routernum => $routernum } ) ? ' CHECKED' : ''%> VALUE="ON"> + <A HREF="<%=${p}%>edit/part_svc.cgi?<%=$part_svc->svcpart%>"> + <%=$part_svc->svcpart%>: <%=$part_svc->svc%></A> + <% } %> + +<% } %> + + <BR><BR><INPUT TYPE="submit" VALUE="Apply changes"> + </FORM> +</BODY></HTML> + diff --git a/httemplate/edit/svc_acct.cgi b/httemplate/edit/svc_acct.cgi index 90b26324a..f1b8b800b 100755 --- a/httemplate/edit/svc_acct.cgi +++ b/httemplate/edit/svc_acct.cgi @@ -35,8 +35,6 @@ if ( $cgi->param('error') ) { } else { #adding - $svc_acct = new FS::svc_acct({}); - foreach $_ (split(/-/,$query)) { $pkgnum=$1 if /^pkgnum(\d+)$/; $svcpart=$1 if /^svcpart(\d+)$/; @@ -44,6 +42,8 @@ if ( $cgi->param('error') ) { $part_svc = qsearchs( 'part_svc', { 'svcpart' => $svcpart } ); die "No part_svc entry for svcpart $svcpart!" unless $part_svc; + $svc_acct = new FS::svc_acct({svcpart => $svcpart}); + $svcnum=''; #set gecos @@ -72,6 +72,12 @@ if ( $cgi->param('error') ) { } } + +#fixed radius groups always override & display +if ( $part_svc->part_svc_column('usergroup')->columnflag eq "F" ) { + @groups = split(',', $part_svc->part_svc_column('usergroup')->columnvalue); +} + my $action = $svcnum ? 'Edit' : 'Add'; my $svc = $part_svc->getfield('svc'); @@ -163,7 +169,7 @@ if ( $part_svc->part_svc_column('domsvc')->columnflag eq 'F' ) { } my $cust_pkg = qsearchs('cust_pkg', { 'pkgnum' => $pkgnum } ); - if ($cust_pkg) { + if ($cust_pkg && !$conf->exists('svc_acct-alldomains') ) { my @cust_svc = map { qsearch('cust_svc', { 'pkgnum' => $_->pkgnum } ) } qsearch('cust_pkg', { 'custnum' => $cust_pkg->custnum } ); @@ -238,7 +244,16 @@ my($quota,$slipip)=( $svc_acct->slipip, ); -print qq!<INPUT TYPE="hidden" NAME="quota" VALUE="$quota">!; +if ( $part_svc->part_svc_column('quota')->columnflag eq "F" ) +{ + print qq!<INPUT TYPE="hidden" NAME="quota" VALUE="$quota">!; +} else { + print <<END; + <TR><TD ALIGN="right">Quota:</TD> + <TD> <INPUT TYPE="text" NAME="quota" VALUE="$quota" ></TD> + </TR> +END +} if ( $part_svc->part_svc_column('slipip')->columnflag eq "F" ) { print qq!<INPUT TYPE="hidden" NAME="slipip" VALUE="$slipip">!; @@ -266,6 +281,14 @@ if ( $part_svc->part_svc_column('usergroup')->columnflag eq "F" ) { } print '</TD></TR>'; +foreach my $field ($svc_acct->virtual_fields) { + if ( $part_svc->part_svc_column($field)->columnflag ne 'F' ) { + # If the flag is X, it won't even show up in $svc_acct->virtual_fields. + print $svc_acct->pvf($field)->widget('HTML', 'edit', + $svc_acct->getfield($field)); + } +} + #submit print qq!</TABLE><BR><INPUT TYPE="submit" VALUE="Submit">!; diff --git a/httemplate/edit/svc_acct_sm.cgi b/httemplate/edit/svc_acct_sm.cgi deleted file mode 100755 index 0fd5f7622..000000000 --- a/httemplate/edit/svc_acct_sm.cgi +++ /dev/null @@ -1,178 +0,0 @@ -<!-- mason kludge --> -<% - -my $conf = new FS::Conf; -my $mydomain = $conf->config('domain'); - -my($svcnum, $pkgnum, $svcpart, $part_svc, $svc_acct_sm ); -if ( $cgi->param('error') ) { - $svc_acct_sm = new FS::svc_acct_sm ( { - map { $_, scalar($cgi->param($_)) } fields('svc_acct_sm') - } ); - $svcnum = $svc_acct_sm->svcnum; - $pkgnum = $cgi->param('pkgnum'); - $svcpart = $cgi->param('svcpart'); - #$part_svc=qsearchs('part_svc',{'svcpart'=>$svcpart}); - #die "No part_svc entry!" unless $part_svc; -} else { - my($query) = $cgi->keywords; - if ( $query =~ /^(\d+)$/ ) { #editing - $svcnum=$1; - $svc_acct_sm=qsearchs('svc_acct_sm',{'svcnum'=>$svcnum}) - or die "Unknown (svc_acct_sm) svcnum!"; - - my($cust_svc)=qsearchs('cust_svc',{'svcnum'=>$svcnum}) - or die "Unknown (cust_svc) svcnum!"; - - $pkgnum=$cust_svc->pkgnum; - $svcpart=$cust_svc->svcpart; - - #$part_svc=qsearchs('part_svc',{'svcpart'=>$svcpart}); - #die "No part_svc entry!" unless $part_svc; - - } else { #adding - - $svc_acct_sm = new FS::svc_acct_sm({}); - - foreach $_ (split(/-/,$query)) { #get & untaint pkgnum & svcpart - $pkgnum=$1 if /^pkgnum(\d+)$/; - $svcpart=$1 if /^svcpart(\d+)$/; - } - my $part_svc=qsearchs('part_svc',{'svcpart'=>$svcpart}); - die "No part_svc entry!" unless $part_svc; - - $svcnum=''; - - #set fixed and default fields from part_svc - foreach my $part_svc_column ( - grep { $_->columnflag } $part_svc->all_part_svc_column - ) { - $svc_acct_sm->setfield( $part_svc_column->columnname, - $part_svc_column->columnvalue, - ); - } - - } -} -my $action = $svc_acct_sm->svcnum ? 'Edit' : 'Add'; - -my %username = (); -my %domain = (); -if ($pkgnum) { - - #find all possible uids (and usernames) - - my @u_acct_svcparts = (); - foreach my $u_part_svc ( qsearch('part_svc',{'svcdb'=>'svc_acct'}) ) { - push @u_acct_svcparts,$u_part_svc->getfield('svcpart'); - } - - my($cust_pkg)=qsearchs('cust_pkg',{'pkgnum'=>$pkgnum}); - my($custnum)=$cust_pkg->getfield('custnum'); - foreach my $i_cust_pkg ( qsearch('cust_pkg',{'custnum'=>$custnum}) ) { - my($cust_pkgnum)=$i_cust_pkg->getfield('pkgnum'); - my($acct_svcpart); - foreach $acct_svcpart (@u_acct_svcparts) { #now find the corresponding - #record(s) in cust_svc ( for this - #pkgnum ! ) - my($i_cust_svc); - foreach $i_cust_svc ( qsearch('cust_svc',{'pkgnum'=>$cust_pkgnum,'svcpart'=>$acct_svcpart}) ) { - my($svc_acct)=qsearchs('svc_acct',{'svcnum'=>$i_cust_svc->getfield('svcnum')}); - $username{$svc_acct->getfield('uid')}=$svc_acct->getfield('username'); - } - } - } - - #find all possible domains (and domsvc's) - - my @d_acct_svcparts = (); - foreach my $d_part_svc ( qsearch('part_svc',{'svcdb'=>'svc_domain'}) ) { - push @d_acct_svcparts,$d_part_svc->getfield('svcpart'); - } - - foreach $i_cust_pkg ( qsearch('cust_pkg',{'custnum'=>$custnum}) ) { - my($cust_pkgnum)=$i_cust_pkg->getfield('pkgnum'); - my($acct_svcpart); - foreach $acct_svcpart (@d_acct_svcparts) { - my($i_cust_svc); - foreach $i_cust_svc ( qsearch('cust_svc',{'pkgnum'=>$cust_pkgnum,'svcpart'=>$acct_svcpart}) ) { - my($svc_domain)=qsearch('svc_domain',{'svcnum'=>$i_cust_svc->getfield('svcnum')}); - $domain{$svc_domain->getfield('svcnum')}=$svc_domain->getfield('domain'); - } - } - } - -} elsif ( $action eq 'Edit' ) { - - my($svc_acct)=qsearchs('svc_acct',{'uid'=>$svc_acct_sm->domuid}); - $username{$svc_acct_sm->uid} = $svc_acct->username; - - my($svc_domain)=qsearchs('svc_domain',{'svcnum'=>$svc_acct_sm->domsvc}); - $domain{$svc_acct_sm->domsvc} = $svc_domain->domain; - -} else { - die "\$action eq Add, but \$pkgnum is null!\n"; -} - -my $p1 = popurl(1); -print header("Mail Alias $action", ''); - -print qq!<FONT SIZE="+1" COLOR="#ff0000">Error: !, $cgi->param('error'), - "</FONT>" - if $cgi->param('error'); - -print qq!<FORM ACTION="${p1}process/svc_acct_sm.cgi" METHOD=POST>!; - -#display - - #formatting - print "<PRE>"; - -#svcnum -print qq!<INPUT TYPE="hidden" NAME="svcnum" VALUE="$svcnum">!; -print qq!Service #<FONT SIZE=+1><B>!, $svcnum ? $svcnum : " (NEW)", "</B></FONT>"; - -#pkgnum -print qq!<INPUT TYPE="hidden" NAME="pkgnum" VALUE="$pkgnum">!; - -#svcpart -print qq!<INPUT TYPE="hidden" NAME="svcpart" VALUE="$svcpart">!; - -my($domuser,$domsvc,$domuid)=( - $svc_acct_sm->domuser, - $svc_acct_sm->domsvc, - $svc_acct_sm->domuid, -); - -#domuser -print qq!\n\nMail to <INPUT TYPE="text" NAME="domuser" VALUE="$domuser"> <I>( * for anything )</I>!; - -#domsvc -print qq! \@ <SELECT NAME="domsvc" SIZE=1>!; -foreach $_ (keys %domain) { - print "<OPTION", $_ eq $domsvc ? " SELECTED" : "", - qq! VALUE="$_">$domain{$_}!; -} -print "</SELECT>"; - -#uid -print qq!\nforwards to <SELECT NAME="domuid" SIZE=1>!; -foreach $_ (keys %username) { - print "<OPTION", ($_ eq $domuid) ? " SELECTED" : "", - qq! VALUE="$_">$username{$_}!; -} -print "</SELECT>\@$mydomain mailbox."; - - #formatting - print "</PRE>\n"; - -print qq!<CENTER><INPUT TYPE="submit" VALUE="Submit"></CENTER>!; - -print <<END; - - </FORM> - </BODY> -</HTML> -END - -%> diff --git a/httemplate/edit/svc_broadband.cgi b/httemplate/edit/svc_broadband.cgi new file mode 100644 index 000000000..db27b3241 --- /dev/null +++ b/httemplate/edit/svc_broadband.cgi @@ -0,0 +1,172 @@ +<!-- mason kludge --> +<% + +# If it's stupid but it works, it's still stupid. +# -Kristian + + +use HTML::Widgets::SelectLayers; +use Tie::IxHash; + +my( $svcnum, $pkgnum, $svcpart, $part_svc, $svc_broadband ); +if ( $cgi->param('error') ) { + $svc_broadband = new FS::svc_broadband ( { + map { $_, scalar($cgi->param($_)) } fields('svc_broadband') + } ); + $svcnum = $svc_broadband->svcnum; + $pkgnum = $cgi->param('pkgnum'); + $svcpart = $cgi->param('svcpart'); + $part_svc=qsearchs('part_svc',{'svcpart'=>$svcpart}); + die "No part_svc entry!" unless $part_svc; +} else { + my($query) = $cgi->keywords; + if ( $query =~ /^(\d+)$/ ) { #editing + $svcnum=$1; + $svc_broadband=qsearchs('svc_broadband',{'svcnum'=>$svcnum}) + or die "Unknown (svc_broadband) svcnum!"; + + my($cust_svc)=qsearchs('cust_svc',{'svcnum'=>$svcnum}) + or die "Unknown (cust_svc) svcnum!"; + + $pkgnum=$cust_svc->pkgnum; + $svcpart=$cust_svc->svcpart; + + $part_svc=qsearchs('part_svc',{'svcpart'=>$svcpart}); + die "No part_svc entry!" unless $part_svc; + + } else { #adding + + foreach $_ (split(/-/,$query)) { #get & untaint pkgnum & svcpart + $pkgnum=$1 if /^pkgnum(\d+)$/; + $svcpart=$1 if /^svcpart(\d+)$/; + } + $part_svc=qsearchs('part_svc',{'svcpart'=>$svcpart}); + die "No part_svc entry!" unless $part_svc; + + $svc_broadband = new FS::svc_broadband({ svcpart => $svcpart }); + + $svcnum=''; + + #set fixed and default fields from part_svc + foreach my $part_svc_column ( + grep { $_->columnflag } $part_svc->all_part_svc_column + ) { + $svc_broadband->setfield( $part_svc_column->columnname, + $part_svc_column->columnvalue, + ); + } + + } +} +my $action = $svc_broadband->svcnum ? 'Edit' : 'Add'; + +if ($pkgnum) { + + #Nothing? + +} elsif ( $action eq 'Edit' ) { + + #Nothing? + +} else { + die "\$action eq Add, but \$pkgnum is null!\n"; +} + +my $p1 = popurl(1); + +my ($ip_addr, $speed_up, $speed_down, $blocknum) = + ($svc_broadband->ip_addr, + $svc_broadband->speed_up, + $svc_broadband->speed_down, + $svc_broadband->blocknum); + +%> + +<%=header("Broadband Service $action", '')%> + +<% if ($cgi->param('error')) { %> +<FONT SIZE="+1" COLOR="#ff0000">Error: <%=$cgi->param('error')%></FONT><BR> +<% } %> + +Service #<B><%=$svcnum ? $svcnum : "(NEW)"%></B><BR><BR> + +<FORM ACTION="<%=${p1}%>process/svc_broadband.cgi" METHOD=POST> + <INPUT TYPE="hidden" NAME="svcnum" VALUE="<%=$svcnum%>"> + <INPUT TYPE="hidden" NAME="pkgnum" VALUE="<%=$pkgnum%>"> + <INPUT TYPE="hidden" NAME="svcpart" VALUE="<%=$svcpart%>"> + + <%=&ntable("#cccccc",2)%> + <TR> + <TD ALIGN="right">IP Address</TD> + <TD BGCOLOR="#ffffff"> +<% if ( $part_svc->part_svc_column('ip_addr')->columnflag eq 'F' ) { %> + <INPUT TYPE="hidden" NAME="ip_addr" VALUE="<%=$ip_addr%>"><%=$ip_addr%> +<% } else { %> + <INPUT TYPE="text" NAME="ip_addr" VALUE="<%=$ip_addr%>"> +<% } %> + </TD> + </TR> + <TR> + <TD ALIGN="right">Download speed</TD> + <TD BGCOLOR="#ffffff"> +<% if ( $part_svc->part_svc_column('speed_down')->columnflag eq 'F' ) { %> + <INPUT TYPE="hidden" NAME="speed_down" VALUE="<%=$speed_down%>"><%=$speed_down%>Kbps +<% } else { %> + <INPUT TYPE="text" NAME="speed_down" SIZE=5 VALUE="<%=$speed_down%>">Kbps +<% } %> + </TD> + </TR> + <TR> + <TD ALIGN="right">Upload speed</TD> + <TD BGCOLOR="#ffffff"> +<% if ( $part_svc->part_svc_column('speed_up')->columnflag eq 'F' ) { %> + <INPUT TYPE="hidden" NAME="speed_up" VALUE="<%=$speed_up%>"><%=$speed_up%>Kbps +<% } else { %> + <INPUT TYPE="text" NAME="speed_up" SIZE=5 VALUE="<%=$speed_up%>">Kbps +<% } %> + </TD> + </TR> +<% if ($action eq 'Add') { %> + <TR> + <TD ALIGN="right">Router/Block</TD> + <TD BGCOLOR="#ffffff"> + <SELECT NAME="blocknum"> +<% + foreach my $router ($svc_broadband->allowed_routers) { + foreach my $addr_block ($router->addr_block) { +%> + <OPTION VALUE="<%=$addr_block->blocknum%>"<%=($addr_block->blocknum eq $blocknum) ? ' SELECTED' : ''%>> + <%=$router->routername%>:<%=$addr_block->ip_gateway%>/<%=$addr_block->ip_netmask%></OPTION> +<% + } + } +%> + </SELECT> + </TD> + </TR> +<% } else { %> + + <TR> + <TD ALIGN="right">Router/Block</TD> + <TD BGCOLOR="#ffffff"> + <%=$svc_broadband->addr_block->router->routername%>:<%=$svc_broadband->addr_block->NetAddr%> + <INPUT TYPE="hidden" NAME="blocknum" VALUE="<%=$svc_broadband->blocknum%>"> + </TD> + </TR> + +<% } %> + +<% +foreach my $field ($svc_broadband->virtual_fields) { + if ( $part_svc->part_svc_column($field)->columnflag ne 'F' ) { + print $svc_broadband->pvf($field)->widget('HTML', 'edit', + $svc_broadband->getfield($field)); + } +} %> + </TABLE> + <BR> + <INPUT TYPE="submit" NAME="submit" VALUE="Submit"> +</FORM> +</BODY> +</HTML> + diff --git a/httemplate/edit/svc_domain.cgi b/httemplate/edit/svc_domain.cgi index d20e1f336..ca0e3398f 100755 --- a/httemplate/edit/svc_domain.cgi +++ b/httemplate/edit/svc_domain.cgi @@ -87,7 +87,7 @@ print ' CHECKED' if $kludge_action eq 'M'; print qq!>Transfer!; print <<END; -<P>Domain <INPUT TYPE="text" NAME="domain" VALUE="$domain" SIZE=28 MAXLENGTH=26> +<P>Domain <INPUT TYPE="text" NAME="domain" VALUE="$domain" SIZE=28 MAXLENGTH=63> <BR>Purpose/Description: <INPUT TYPE="text" NAME="purpose" VALUE="$purpose" SIZE=64> <P><INPUT TYPE="submit" VALUE="Submit"> </FORM> diff --git a/httemplate/edit/svc_external.cgi b/httemplate/edit/svc_external.cgi new file mode 100644 index 000000000..bcfc85e3f --- /dev/null +++ b/httemplate/edit/svc_external.cgi @@ -0,0 +1,105 @@ +<!-- mason kludge --> +<% + +my( $svcnum, $pkgnum, $svcpart, $part_svc, $svc_external ); +if ( $cgi->param('error') ) { + $svc_external = new FS::svc_external ( { + map { $_, scalar($cgi->param($_)) } fields('svc_external') + } ); + $svcnum = $svc_external->svcnum; + $pkgnum = $cgi->param('pkgnum'); + $svcpart = $cgi->param('svcpart'); + $part_svc=qsearchs('part_svc',{'svcpart'=>$svcpart}); + die "No part_svc entry!" unless $part_svc; +} else { + my($query) = $cgi->keywords; + if ( $query =~ /^(\d+)$/ ) { #editing + $svcnum=$1; + $svc_external=qsearchs('svc_external',{'svcnum'=>$svcnum}) + or die "Unknown (svc_external) svcnum!"; + + my($cust_svc)=qsearchs('cust_svc',{'svcnum'=>$svcnum}) + or die "Unknown (cust_svc) svcnum!"; + + $pkgnum=$cust_svc->pkgnum; + $svcpart=$cust_svc->svcpart; + + $part_svc=qsearchs('part_svc',{'svcpart'=>$svcpart}); + die "No part_svc entry!" unless $part_svc; + + } else { #adding + + foreach $_ (split(/-/,$query)) { #get & untaint pkgnum & svcpart + $pkgnum=$1 if /^pkgnum(\d+)$/; + $svcpart=$1 if /^svcpart(\d+)$/; + } + $svc_external = new FS::svc_external { svcpart => $svcpart }; + + $part_svc=qsearchs('part_svc',{'svcpart'=>$svcpart}); + die "No part_svc entry!" unless $part_svc; + + $svcnum=''; + + #set fixed and default fields from part_svc + foreach my $part_svc_column ( + grep { $_->columnflag } $part_svc->all_part_svc_column + ) { + $svc_external->setfield( $part_svc_column->columnname, + $part_svc_column->columnvalue, + ); + } + + } +} +my $action = $svc_external->svcnum ? 'Edit' : 'Add'; + +my $p1 = popurl(1); +print header("External service $action", ''); + +print qq!<FONT SIZE="+1" COLOR="#ff0000">Error: !, $cgi->param('error'), + "</FONT>" + if $cgi->param('error'); + +print qq!<FORM ACTION="${p1}process/svc_external.cgi" METHOD=POST>!; + +#display + + +#svcnum +print qq!<INPUT TYPE="hidden" NAME="svcnum" VALUE="$svcnum">!; +print qq!Service #<B>!, $svcnum ? $svcnum : "(NEW)", "</B><BR><BR>"; + +#pkgnum +print qq!<INPUT TYPE="hidden" NAME="pkgnum" VALUE="$pkgnum">!; + +#svcpart +print qq!<INPUT TYPE="hidden" NAME="svcpart" VALUE="$svcpart">!; + +my($id,$title)=( + $svc_external->id, + $svc_external->title, +); + +print &ntable("#cccccc",2), + '<TR><TD ALIGN="right">External ID</TD><TD>'. + qq!<INPUT TYPE="text" NAME="id" VALUE="$id">!. + '</TD></TR>'. + '<TR><TD ALIGN="right">Title</TD><TD>'. + qq!<INPUT TYPE="text" NAME="title" VALUE="$title">!. + '</TD></TR>'; + +foreach my $field ($svc_external->virtual_fields) { + if ( $part_svc->part_svc_column($field)->columnflag ne 'F' ) { + # If the flag is X, it won't even show up in $svc_acct->virtual_fields. + print $svc_external->pvf($field)->widget('HTML', 'edit', + $svc_external->getfield($field)); + } +} + +%> + +</TABLE><BR><INPUT TYPE="submit" VALUE="Submit"> + </FORM> + </BODY> +</HTML> + diff --git a/httemplate/edit/svc_forward.cgi b/httemplate/edit/svc_forward.cgi index bc19fe1de..2e6c5f1a0 100755 --- a/httemplate/edit/svc_forward.cgi +++ b/httemplate/edit/svc_forward.cgi @@ -2,7 +2,6 @@ <% my $conf = new FS::Conf; -my $mydomain = $conf->config('domain'); my($svcnum, $pkgnum, $svcpart, $part_svc, $svc_forward); if ( $cgi->param('error') ) { @@ -59,20 +58,17 @@ if ( $cgi->param('error') ) { my $action = $svc_forward->svcnum ? 'Edit' : 'Add'; my %email; + +#starting with those currently attached +foreach my $method (qw( srcsvc_acct dstsvc_acct )) { + my $svc_acct = $svc_forward->$method(); + $email{$svc_acct->svcnum} = $svc_acct->email if $svc_acct; +} + if ($pkgnum) { #find all possible user svcnums (and emails) - #starting with those currently attached - if ( $svc_forward->srcsvc ) { - my $svc_acct = qsearchs( 'svc_acct', { 'svcnum' => $svc_forward->srcsvc } ); - $email{$svc_forward->srcsvc} = $svc_acct->email; - } - if ( $svc_forward->dstsvc ) { - my $svc_acct = qsearchs( 'svc_acct', { 'svcnum' => $svc_forward->dstsvc } ); - $email{$svc_forward->dstsvc} = $svc_acct->email; - } - #and including the rest for this customer my($u_part_svc,@u_acct_svcparts); foreach $u_part_svc ( qsearch('part_svc',{'svcdb'=>'svc_acct'}) ) { @@ -99,15 +95,7 @@ if ($pkgnum) { } } -} elsif ( $action eq 'Edit' ) { - - my($svc_acct)=qsearchs('svc_acct',{'svcnum'=>$svc_forward->srcsvc}); - $email{$svc_forward->srcsvc} = $svc_acct->email; - - $svc_acct=qsearchs('svc_acct',{'svcnum'=>$svc_forward->dstsvc}); - $email{$svc_forward->dstsvc} = $svc_acct->email; - -} else { +} elsif ( $action eq 'Add' ) { die "\$action eq Add, but \$pkgnum is null!\n"; } @@ -116,6 +104,7 @@ my($srcsvc,$dstsvc,$dst)=( $svc_forward->dstsvc, $svc_forward->dst, ); +my $src = $svc_forward->dbdef_table->column('src') ? $svc_forward->src : ''; #display @@ -131,46 +120,54 @@ my($srcsvc,$dstsvc,$dst)=( Service #<%= $svcnum ? "<B>$svcnum</B>" : " (NEW)" %><BR> Service: <B><%= $part_svc->svc %></B><BR><BR> -<FORM NAME="dummy"> +<FORM ACTION="process/svc_forward.cgi" METHOD="POST"> +<INPUT TYPE="hidden" NAME="svcnum" VALUE="<%= $svcnum %>"> +<INPUT TYPE="hidden" NAME="pkgnum" VALUE="<%= $pkgnum %>"> +<INPUT TYPE="hidden" NAME="svcpart" VALUE="<%= $svcpart %>"> + +<SCRIPT TYPE="text/javascript"> +function srcchanged(what) { + if ( what.options[what.selectedIndex].value == 0 ) { + what.form.src.disabled = false; + } else { + what.form.src.disabled = true; + } +} +function dstchanged(what) { + if ( what.options[what.selectedIndex].value == 0 ) { + what.form.dst.disabled = false; + } else { + what.form.dst.disabled = true; + } +} +</SCRIPT> <%= ntable("#cccccc",2) %> -<TR><TD ALIGN="right">Email to</TD><TD><SELECT NAME="srcsvc" SIZE=1> +<TR><TD ALIGN="right">Email to</TD> +<TD><SELECT NAME="srcsvc" SIZE=1 onChange="srcchanged(this)"> <% foreach $_ (keys %email) { %> <OPTION<%= $_ eq $srcsvc ? " SELECTED" : "" %> VALUE="<%= $_ %>"><%= $email{$_} %></OPTION> <% } %> -</SELECT></TD></TR> - -<% - tie my %tied_email, 'Tie::IxHash', - '' => 'SELECT DESTINATION', - %email, - '0' => '(other email address)'; - my $widget = new HTML::Widgets::SelectLayers( - 'selected_layer' => $dstsvc, - 'options' => \%tied_email, - 'form_name' => 'dummy', - 'form_action' => 'process/svc_forward.cgi', - 'form_select' => ['srcsvc'], - 'html_between' => '</TD></TR></TABLE>', - 'layer_callback' => sub { - my $layer = shift; - my $html = qq!<INPUT TYPE="hidden" NAME="svcnum" VALUE="$svcnum">!. - qq!<INPUT TYPE="hidden" NAME="pkgnum" VALUE="$pkgnum">!. - qq!<INPUT TYPE="hidden" NAME="svcpart" VALUE="$svcpart">!. - qq!<INPUT TYPE="hidden" NAME="dstsvc" VALUE="$layer">!; - if ( $layer eq '0' ) { - $html .= ntable("#cccccc",2). - '<TR><TD ALIGN="right">Destination email</TD>'. - qq!<TD><INPUT TYPE="text" NAME="dst" VALUE="$dst"></TD>!. - '</TR></TABLE>'; - } - $html .= '<BR><INPUT TYPE="submit" VALUE="Submit">'; - $html; - }, - ); -%> +<% if ( $svc_forward->dbdef_table->column('src') ) { %> + <OPTION <%= $src ? 'SELECTED' : '' %> VALUE="0">(other email address)</OPTION> +<% } %> +</SELECT> +<% if ( $svc_forward->dbdef_table->column('src') ) { %> +<INPUT TYPE="text" NAME="src" VALUE="<%= $src %>" <%= ( $src || !scalar(%email) ) ? '' : 'DISABLED' %>> +<% } %> +</TD></TR> <TR><TD ALIGN="right">Forwards to</TD> -<TD><%= $widget->html %> +<TD><SELECT NAME="dstsvc" SIZE=1 onChange="dstchanged(this)"> +<% foreach $_ (keys %email) { %> + <OPTION<%= $_ eq $dstsvc ? " SELECTED" : "" %> VALUE="<%= $_ %>"><%= $email{$_} %></OPTION> +<% } %> +<OPTION <%= $dst ? 'SELECTED' : '' %> VALUE="0">(other email address)</OPTION> +</SELECT> +<INPUT TYPE="text" NAME="dst" VALUE="<%= $dst %>" <%= ( $dst || !scalar(%email) ) ? '' : 'DISABLED' %>> +</TD></TR> + </TABLE> +<BR><INPUT TYPE="submit" VALUE="Submit"> +</FORM> </BODY> </HTML> diff --git a/httemplate/edit/svc_www.cgi b/httemplate/edit/svc_www.cgi index d2c9ade5c..ec5169e05 100644 --- a/httemplate/edit/svc_www.cgi +++ b/httemplate/edit/svc_www.cgi @@ -29,12 +29,12 @@ if ( $cgi->param('error') ) { } else { #adding - $svc_www = new FS::svc_www({}); - foreach $_ (split(/-/,$query)) { #get & untaint pkgnum & svcpart $pkgnum=$1 if /^pkgnum(\d+)$/; $svcpart=$1 if /^svcpart(\d+)$/; } + $svc_www = new FS::svc_www { svcpart => $svcpart }; + $part_svc=qsearchs('part_svc',{'svcpart'=>$svcpart}); die "No part_svc entry!" unless $part_svc; @@ -167,6 +167,14 @@ foreach $_ (keys %username) { } print "</SELECT></TD></TR>"; +foreach my $field ($svc_www->virtual_fields) { + if ( $part_svc->part_svc_column($field)->columnflag ne 'F' ) { + # If the flag is X, it won't even show up in $svc_acct->virtual_fields. + print $svc_www->pvf($field)->widget('HTML', 'edit', + $svc_www->getfield($field)); + } +} + print '</TABLE><BR><INPUT TYPE="submit" VALUE="Submit">'; print <<END; |