summaryrefslogtreecommitdiff
path: root/httemplate/edit
diff options
context:
space:
mode:
Diffstat (limited to 'httemplate/edit')
-rwxr-xr-xhttemplate/edit/REAL_cust_pkg.cgi64
-rwxr-xr-xhttemplate/edit/agent.cgi65
-rwxr-xr-xhttemplate/edit/cust_main.cgi213
-rwxr-xr-xhttemplate/edit/cust_main_county.cgi44
-rwxr-xr-xhttemplate/edit/part_bill_event.cgi40
-rw-r--r--httemplate/edit/part_export.cgi19
-rwxr-xr-xhttemplate/edit/part_pkg.cgi199
-rwxr-xr-xhttemplate/edit/part_svc.cgi114
-rw-r--r--httemplate/edit/part_virtual_field.cgi92
-rwxr-xr-xhttemplate/edit/process/REAL_cust_pkg.cgi2
-rwxr-xr-xhttemplate/edit/process/addr_block/add.cgi20
-rwxr-xr-xhttemplate/edit/process/addr_block/allocate.cgi25
-rwxr-xr-xhttemplate/edit/process/addr_block/deallocate.cgi24
-rwxr-xr-xhttemplate/edit/process/addr_block/split.cgi19
-rwxr-xr-xhttemplate/edit/process/cust_main.cgi22
-rwxr-xr-xhttemplate/edit/process/cust_main_county-collapse.cgi4
-rwxr-xr-xhttemplate/edit/process/cust_main_county.cgi21
-rwxr-xr-xhttemplate/edit/process/cust_pkg.cgi25
-rw-r--r--httemplate/edit/process/generic.cgi70
-rwxr-xr-xhttemplate/edit/process/part_bill_event.cgi2
-rwxr-xr-xhttemplate/edit/process/part_pkg.cgi16
-rwxr-xr-xhttemplate/edit/process/part_svc.cgi2
-rw-r--r--httemplate/edit/process/router.cgi67
-rwxr-xr-xhttemplate/edit/process/svc_acct_sm.cgi34
-rw-r--r--httemplate/edit/process/svc_broadband.cgi45
-rwxr-xr-xhttemplate/edit/process/svc_external.cgi29
-rwxr-xr-xhttemplate/edit/router.cgi77
-rwxr-xr-xhttemplate/edit/svc_acct.cgi31
-rwxr-xr-xhttemplate/edit/svc_acct_sm.cgi178
-rw-r--r--httemplate/edit/svc_broadband.cgi172
-rwxr-xr-xhttemplate/edit/svc_domain.cgi2
-rw-r--r--httemplate/edit/svc_external.cgi105
-rwxr-xr-xhttemplate/edit/svc_forward.cgi105
-rw-r--r--httemplate/edit/svc_www.cgi12
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>&nbsp;!;
-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&nbsp;(<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>)&nbsp;<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&nbsp;(<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>)&nbsp;<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>&nbsp;&nbsp;<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;