summaryrefslogtreecommitdiff
path: root/httemplate/edit
diff options
context:
space:
mode:
authorkhoff <khoff>2002-09-09 23:05:30 +0000
committerkhoff <khoff>2002-09-09 23:05:30 +0000
commit44398c83f25bf4e43838df9f39331c29fdeff19d (patch)
tree963837373a3b621ee2140adad0eb0b44e12c75e6 /httemplate/edit
parent91292eadb6254740a9b72e5dc95f575593f6a35d (diff)
svc_broadband merge
Diffstat (limited to 'httemplate/edit')
-rwxr-xr-xhttemplate/edit/ac.cgi163
-rwxr-xr-xhttemplate/edit/ac_type.cgi106
-rwxr-xr-xhttemplate/edit/part_svc.cgi13
-rwxr-xr-xhttemplate/edit/process/ac.cgi28
-rwxr-xr-xhttemplate/edit/process/ac_block.cgi21
-rwxr-xr-xhttemplate/edit/process/ac_field.cgi21
-rwxr-xr-xhttemplate/edit/process/ac_type.cgi28
-rwxr-xr-xhttemplate/edit/process/part_ac_field.cgi21
-rwxr-xr-xhttemplate/edit/process/part_svc.cgi2
-rw-r--r--httemplate/edit/process/svc_broadband.cgi45
-rw-r--r--httemplate/edit/svc_broadband.cgi219
11 files changed, 665 insertions, 2 deletions
diff --git a/httemplate/edit/ac.cgi b/httemplate/edit/ac.cgi
new file mode 100755
index 000000000..86b05a4a1
--- /dev/null
+++ b/httemplate/edit/ac.cgi
@@ -0,0 +1,163 @@
+<!-- mason kludge -->
+<%
+
+my($ac);
+if ( $cgi->param('error') ) {
+ $ac = new FS::ac ( {
+ map { $_, scalar($cgi->param($_)) } fields('ac')
+ } );
+} elsif ( $cgi->keywords ) { #editing
+ my( $query ) = $cgi->keywords;
+ $query =~ /^(\d+)$/;
+ $ac=qsearchs('ac',{'acnum'=>$1});
+} else { #adding
+ $ac = new FS::ac {};
+}
+my $action = $ac->acnum ? 'Edit' : 'Add';
+my $hashref = $ac->hashref;
+
+print header("$action Access Concentrator", menubar(
+ 'Main Menu' => "$p",
+ 'View all access concentrators' => "${p}browse/ac.cgi",
+));
+
+print qq!<FONT SIZE="+1" COLOR="#ff0000">Error: !, $cgi->param('error'),
+ "</FONT>"
+ if $cgi->param('error');
+
+print '<FORM ACTION="', popurl(1), 'process/ac.cgi" METHOD=POST>',
+ qq!<INPUT TYPE="hidden" NAME="acnum" VALUE="$hashref->{acnum}">!,
+ "Access Concentrator #", $hashref->{acnum} ? $hashref->{acnum} : "(NEW)";
+
+print <<END;
+
+<TABLE COLOR="#cccccc">
+ <TR>
+ <TH ALIGN="RIGHT">Access Concentrator</TH>
+ <TD>
+ <INPUT TYPE="text" NAME="acname" SIZE=15 VALUE="$hashref->{acname}">
+ </TD>
+ </TD>
+END
+
+
+if (! $ac->acnum) {
+ print <<END;
+ <TR>
+ <TH ALIGN="RIGHT">Access Concentrator Type</TH>
+ <TD><SELECT NAME="actypenum" SIZE="1"><OPTION VALUE=""></OPTION>
+END
+
+ foreach (qsearch('ac_type', {})) {
+ my $narf = $_->hashref;
+ print qq!<OPTION! .
+ ($narf->{actypenum} eq $hashref->{actypenum} ? ' SELECTED' : '') .
+ qq! VALUE="$narf->{actypenum}">$narf->{actypenum}: $narf->{actypename}! .
+ qq!</OPTION>!;
+ }
+
+ print '</TD></TR></TABLE>';
+} else {
+ print '</TABLE>';
+ print qq!<INPUT TYPE="hidden" NAME="actypenum" VALUE="$hashref->{actypenum}">!;
+}
+
+print qq!</TABLE><BR><BR><INPUT TYPE="submit" VALUE="!,
+ $hashref->{acnum} ? "Apply changes" : "Add access concentrator",
+ qq!"></FORM>!;
+
+if ($hashref->{acnum}) {
+ print table();
+ print <<END;
+ Additional Fields:<BR>
+ <TH>
+ <TD>Field Name</TD>
+ <TD COLSPAN=2>Field Value</TD>
+ </TH>
+END
+
+ #my @ac_fields = qsearch('ac_field', { acnum => $hashref->{acnum} });
+ my @ac_fields = $ac->ac_field;
+ foreach (@ac_fields) {
+ print qq!\n<TR><TD></TD>!;
+ my $part_ac_field = qsearchs('part_ac_field',
+ { acfieldpart => $_->getfield('acfieldpart') });
+ print '<TD>' . $part_ac_field->getfield('name') .
+ '</TD><TD>' . $_->getfield('value') . '</TD></TR>';
+ print "\n";
+ }
+
+ print '<FORM ACTION="', popurl(1), 'process/ac_field.cgi" METHOD=POST>';
+ print <<END;
+ <TR>
+ <TD><INPUT TYPE="hidden" NAME="acnum" VALUE="$hashref->{acnum}">
+ <INPUT TYPE="hidden" NAME="acname" VALUE="$hashref->{acname}">
+ <INPuT TYPE="hidden" NAME="actypenum" VALUE="$hashref->{actypenum}">
+ <SMALL>(NEW)</SMALL>
+ </TD>
+ <TD><SELECT NAME="acfieldpart"><OPTION></OPTION>
+END
+
+ my @part_ac_fields = qsearch('part_ac_field',
+ { actypenum => $hashref->{actypenum} });
+ foreach my $part_ac_field (@part_ac_fields) {
+ my $acfieldpart = $part_ac_field->getfield('acfieldpart');
+ if (grep {$_->getfield('acfieldpart') eq $acfieldpart} @ac_fields) {next;}
+ print qq!<OPTION VALUE="${acfieldpart}">! .
+ $part_ac_field->getfield('name') . '</OPTION>';
+ }
+
+ print <<END;
+ </SELECT>
+ </TD>
+ <TD><INPUT TYPE="text" SIZE="15" NAME="value"></TD>
+ <TD><INPUT TYPE="submit" VALUE="Add"></TD>
+ </TR>
+ </FORM>
+ </TABLE>
+END
+
+}
+
+if ($hashref->{acnum}) {
+
+ print qq!<BR><BR>IP Address Blocks:<BR>! . table() .
+ qq!<TR><TH></TH><TH>Network/Mask</TH>! .
+ qq!<TH>Gateway Address</TH><TH>Mask length</TH></TR>\n!;
+
+ foreach (qsearch('ac_block', { acnum => $hashref->{acnum} })) {
+ my $ip_addr = new NetAddr::IP($_->getfield('ip_gateway'),
+ $_->getfield('ip_netmask'));
+ print qq!<TR><TD></TD><TD>! . $ip_addr->network->addr() . '/' .
+ $ip_addr->network->mask() . qq!</TD>!;
+
+ print qq!<TD>! . $_->getfield('ip_gateway') . qq!</TD>\n! .
+ qq!<TD>! . $_->getfield('ip_netmask') . qq!</TD></TR>!;
+
+ }
+
+ print '<FORM ACTION="', popurl(1), 'process/ac_block.cgi" METHOD=POST>';
+ print <<END;
+ <TR>
+ <TD><INPUT TYPE="hidden" NAME="acnum" VALUE="$hashref->{acnum}">
+ <INPUT TYPE="hidden" NAME="acname" VALUE="$hashref->{acname}">
+ <INPuT TYPE="hidden" NAME="actypenum" VALUE="$hashref->{actypenum}">
+ <SMALL>(NEW)</SMALL>
+ </TD>
+ <TD></TD>
+ <TD><INPUT TYPE="text" NAME="ip_gateway" SIZE="15"></TD>
+ <TD><INPUT TYPE="text" NAME="ip_netmask" SIZE="2"></TD>
+ <TD><INPUT TYPE="submit" VALUE="Add"></TD>
+ </TR>
+ </FORM>
+</TABLE>
+END
+
+}
+
+print <<END;
+ </BODY>
+</HTML>
+END
+
+%>
diff --git a/httemplate/edit/ac_type.cgi b/httemplate/edit/ac_type.cgi
new file mode 100755
index 000000000..ccc3d579c
--- /dev/null
+++ b/httemplate/edit/ac_type.cgi
@@ -0,0 +1,106 @@
+<!-- mason kludge -->
+<%
+
+my $ac_type;
+if ( $cgi->param('error') ) {
+ $ac_type = new FS::ac_type ( {
+ map { $_, scalar($cgi->param($_)) } fields('ac_type')
+ } );
+} elsif ( $cgi->keywords ) { #editing
+ my($query)=$cgi->keywords;
+ $query =~ /^(\d+)$/;
+ $ac_type=qsearchs('ac_type',{'actypenum'=>$1});
+} else { #adding
+ $ac_type = new FS::ac_type {};
+}
+my $action = $ac_type->actypenum ? 'Edit' : 'Add';
+my $hashref = $ac_type->hashref;
+
+my @ut_types = qw( float number text alpha anything ip domain );
+
+my $p1 = popurl(1);
+print header("$action Access Concentrator Type", menubar(
+ 'Main Menu' => popurl(2),
+ 'View all Access Concentrator types' => popurl(2). "browse/ac_type.cgi",
+));
+
+print qq!<FONT SIZE="+1" COLOR="#ff0000">Error: !, $cgi->param('error'),
+ "</FONT>"
+ if $cgi->param('error');
+
+print qq!<FORM ACTION="${p1}process/ac_type.cgi" METHOD=POST>!;
+
+#display
+
+print qq!<INPUT TYPE="hidden" NAME="actypenum" VALUE="$hashref->{actypenum}">!,
+ "AC Type #", $hashref->{actypenum} ? $hashref->{actypenum} : "(NEW)";
+
+print <<TROZ;
+<PRE>
+AC Type Name <INPUT TYPE="text" NAME="actypename" SIZE=15 VALUE="$hashref->{actypename}">
+</PRE>
+
+TROZ
+
+print qq!<BR><INPUT TYPE="submit" VALUE="!,
+ $hashref->{actypenum} ? "Apply changes" : "Add AC Type",
+ qq!"></FORM>!;
+
+
+if ($hashref->{actypenum}) {
+ print qq! <BR>Available fields:<BR>! . table();
+
+ print qq! <TH><TD>Field name</TD><TD>Field type</TD><TD></TD></TH>!;
+
+ my @part_ac_field = qsearch ( 'part_ac_field',
+ { actypenum => $hashref->{actypenum} } );
+ foreach ( @part_ac_field ) {
+ my $pf_hashref = $_->hashref;
+ print <<END;
+ <TR>
+ <TD>$pf_hashref->{acfieldpart}</TD>
+ <TD>$pf_hashref->{name}</TD>
+ <TD>$pf_hashref->{ut_type}</TD>
+ </TR>
+END
+ }
+
+ my $name, $ut_type = '';
+ if ($cgi->param('error')) {
+ $name = $cgi->param('name');
+ $ut_type = $cgi->param('ut_type');
+ }
+
+ print <<END;
+ <FORM ACTION="${p1}process/part_ac_field.cgi" METHOD=GET>
+ <TR>
+ <TD><SMALL>(NEW)</SMALL>
+ <INPUT TYPE="hidden" NAME="actypenum" VALUE="$hashref->{actypenum}">
+ </TD>
+ <TD>
+ <INPUT TYPE="text" NAME="name" VALUE="${name}">
+ </TD>
+ <TD>
+ <SELECT NAME="ut_type" SIZE=1><OPTION>
+END
+
+ foreach ( @ut_types ) {
+ print qq!<OPTION! . ($ut_type ? " SELECTED>$_" : ">$_");
+ }
+
+ print <<END;
+ </SELECT>
+ </TD>
+ <TD><INPUT TYPE="submit" VALUE="Add"></TD>
+ </TR>
+ </FORM>
+ </TABLE>
+END
+
+}
+
+%>
+
+ </BODY>
+</HTML>
+
diff --git a/httemplate/edit/part_svc.cgi b/httemplate/edit/part_svc.cgi
index 4ccb770fb..a23107a40 100755
--- a/httemplate/edit/part_svc.cgi
+++ b/httemplate/edit/part_svc.cgi
@@ -53,6 +53,7 @@ Services are items you offer to your customers.
<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_charge - One-time charges (Partially unimplemented)
<LI>svc_wo - Work orders (Partially unimplemented)
-->
@@ -122,11 +123,21 @@ my %defs = (
#'recnum' => '',
#'usersvc' => '',
},
+ 'svc_broadband' => {
+ 'actypenum' => 'This is the actypenum that refers to the type of AC that can be provisioned for this service. This field must be set fixed.',
+ '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.',
+ 'acnum' => 'acnum of a specific AC that this service is restricted to. Not required',
+ 'ip_addr' => 'IP address. Leave blank for automatic assignment.',
+ 'ip_netmask' => 'Mask length, aka. netmask bits. (Eg. 255.255.255.0 == 24)',
+ 'mac_addr' => 'MAC address which is used by some ACs for access control. Specified by 6 colon seperated hex octets. (Eg. 00:00:0a:bc:1a:2b)',
+ 'location' => 'Defines the physically location at which this service was installed. This is not necessarily the billing address',
+ },
);
my @dbs = $hashref->{svcdb}
? ( $hashref->{svcdb} )
- : qw( svc_acct svc_domain svc_acct_sm svc_forward svc_www );
+ : qw( svc_acct svc_domain svc_acct_sm svc_forward svc_www svc_broadband );
tie my %svcdb, 'Tie::IxHash', map { $_=>$_ } @dbs;
my $widget = new HTML::Widgets::SelectLayers(
diff --git a/httemplate/edit/process/ac.cgi b/httemplate/edit/process/ac.cgi
new file mode 100755
index 000000000..fc434a807
--- /dev/null
+++ b/httemplate/edit/process/ac.cgi
@@ -0,0 +1,28 @@
+<%
+
+my $acnum = $cgi->param('acnum');
+
+my $old = qsearchs('ac',{'acnum'=>$acnum}) if $acnum;
+
+my $new = new FS::ac ( {
+ map {
+ $_, scalar($cgi->param($_));
+ } fields('ac')
+} );
+
+my $error = '';
+if ( $acnum ) {
+ $error = $new->replace($old);
+} else {
+ $error = $new->insert;
+ $acnum=$new->getfield('acnum');
+}
+
+if ( $error ) {
+ $cgi->param('error', $error);
+ print $cgi->redirect(popurl(2). "ac.cgi?". $cgi->query_string );
+} else {
+ print $cgi->redirect(popurl(3). "browse/ac.cgi");
+}
+
+%>
diff --git a/httemplate/edit/process/ac_block.cgi b/httemplate/edit/process/ac_block.cgi
new file mode 100755
index 000000000..b1c3c726b
--- /dev/null
+++ b/httemplate/edit/process/ac_block.cgi
@@ -0,0 +1,21 @@
+<%
+
+my $new = new FS::ac_block ( {
+ map {
+ $_, scalar($cgi->param($_));
+ } fields('ac_block')
+} );
+
+my $error = '';
+$error = $new->check;
+
+unless ( $error ) { $error = $new->insert; }
+
+if ( $error ) {
+ $cgi->param('error', $error);
+ print $cgi->redirect(popurl(2). "ac.cgi?". $cgi->query_string );
+} else {
+ print $cgi->redirect(popurl(2). "ac.cgi?". $cgi->param('acnum'));
+}
+
+%>
diff --git a/httemplate/edit/process/ac_field.cgi b/httemplate/edit/process/ac_field.cgi
new file mode 100755
index 000000000..2bfe3312f
--- /dev/null
+++ b/httemplate/edit/process/ac_field.cgi
@@ -0,0 +1,21 @@
+<%
+
+my $new = new FS::ac_field ( {
+ map {
+ $_, scalar($cgi->param($_));
+ } fields('ac_field')
+} );
+
+my $error = '';
+$error = $new->check;
+
+unless ( $error ) { $error = $new->insert; }
+
+if ( $error ) {
+ $cgi->param('error', $error);
+ print $cgi->redirect(popurl(2). "ac.cgi?". $cgi->query_string );
+} else {
+ print $cgi->redirect(popurl(2). "ac.cgi?". $cgi->param('acnum'));
+}
+
+%>
diff --git a/httemplate/edit/process/ac_type.cgi b/httemplate/edit/process/ac_type.cgi
new file mode 100755
index 000000000..ca232ba58
--- /dev/null
+++ b/httemplate/edit/process/ac_type.cgi
@@ -0,0 +1,28 @@
+<%
+
+my $actypenum = $cgi->param('actypenum');
+
+my $old = qsearchs('ac_type',{'actypenum'=>$actypenum}) if $actypenum;
+
+my $new = new FS::ac_type ( {
+ map {
+ $_, scalar($cgi->param($_));
+ } fields('ac_type')
+} );
+
+my $error = '';
+if ( $actypenum ) {
+ $error = $new->replace($old);
+} else {
+ $error = $new->insert;
+ $actypenum=$new->getfield('actypenum');
+}
+
+if ( $error ) {
+ $cgi->param('error', $error);
+ print $cgi->redirect(popurl(2). "ac_type.cgi?". $cgi->query_string );
+} else {
+ print $cgi->redirect(popurl(3). "browse/ac_type.cgi");
+}
+
+%>
diff --git a/httemplate/edit/process/part_ac_field.cgi b/httemplate/edit/process/part_ac_field.cgi
new file mode 100755
index 000000000..38ad586f7
--- /dev/null
+++ b/httemplate/edit/process/part_ac_field.cgi
@@ -0,0 +1,21 @@
+<%
+
+my $new = new FS::part_ac_field ( {
+ map {
+ $_, scalar($cgi->param($_));
+ } fields('part_ac_field')
+} );
+
+my $error = '';
+$error = $new->check;
+
+unless ( $error ) { $error = $new->insert; }
+
+if ( $error ) {
+ $cgi->param('error', $error);
+ print $cgi->redirect(popurl(2). "ac_type.cgi?". $cgi->query_string );
+} else {
+ print $cgi->redirect(popurl(2). "ac_type.cgi?". $cgi->param('actypenum'));
+}
+
+%>
diff --git a/httemplate/edit/process/part_svc.cgi b/httemplate/edit/process/part_svc.cgi
index 859670b17..69e8ac2fa 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_acct_sm svc_forward svc_www svc_broadband )
)
} );
diff --git a/httemplate/edit/process/svc_broadband.cgi b/httemplate/edit/process/svc_broadband.cgi
new file mode 100644
index 000000000..fd7ba20d5
--- /dev/null
+++ b/httemplate/edit/process/svc_broadband.cgi
@@ -0,0 +1,45 @@
+<%
+
+$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 ) )
+} );
+
+unless ( $new->ip_addr ) {
+ $new->ip_addr(join('.', (map $cgi->param('ip_addr_'.$_), (a..d))));
+}
+
+unless ( $new->mac_addr) {
+ $new->mac_addr(join(':', (map $cgi->param('mac_addr_'.$_), (a..f))));
+}
+
+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);
+ $cgi->param('mac_addr', $new->mac_addr);
+ print $cgi->redirect(popurl(2). "svc_broadband.cgi?". $cgi->query_string );
+} else {
+ print $cgi->redirect(popurl(3). "view/svc_broadband.cgi?" . $svcnum );
+}
+
+%>
diff --git a/httemplate/edit/svc_broadband.cgi b/httemplate/edit/svc_broadband.cgi
new file mode 100644
index 000000000..d8a1f7a2a
--- /dev/null
+++ b/httemplate/edit/svc_broadband.cgi
@@ -0,0 +1,219 @@
+<!-- mason kludge -->
+<%
+
+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
+
+ $svc_broadband = new FS::svc_broadband({});
+
+ 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;
+
+ $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';
+
+my @ac_list;
+
+if ($pkgnum) {
+
+ unless ($svc_broadband->actypenum) {die "actypenum must be set fixed";};
+ @ac_list = qsearch('ac', { actypenum => $svc_broadband->getfield('actypenum') });
+
+} elsif ( $action eq 'Edit' ) {
+
+ #Nothing?
+
+} else {
+ die "\$action eq Add, but \$pkgnum is null!\n";
+}
+
+
+my $p1 = popurl(1);
+print header("Broadband 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_broadband.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">!;
+
+#actypenum
+print '<INPUT TYPE="hidden" NAME="actypenum" VALUE="' .
+ $svc_broadband->actypenum . '">';
+
+
+print &ntable("#cccccc",2) . qq!<TR><TD ALIGN="right">AC</TD><TD>!;
+
+#acnum
+if (( $part_svc->part_svc_column('acnum')->columnflag eq 'F' ) or
+ ( !$pkgnum )) {
+
+ my $ac = qsearchs('ac', { acnum => $svc_broadband->acnum });
+ my ($acnum, $acname) = ($ac->acnum, $ac->acname);
+
+ print qq!<INPUT TYPE="hidden" NAME="acnum" VALUE="${acnum}">! .
+ qq!${acnum}: ${acname}</TD></TR>!;
+
+} else {
+
+ my @ac_list = qsearch('ac', { actypenum => $svc_broadband->actypenum });
+ print qq!<SELECT NAME="acnum" SIZE="1"><OPTION VALUE=""></OPTION>!;
+
+ foreach ( @ac_list ) {
+ my ($acnum, $acname) = ($_->acnum, $_->acname);
+ print qq!<OPTION VALUE="${acnum}"! .
+ ($acnum == $svc_broadband->acnum ? ' SELECTED>' : '>') .
+ qq!${acname}</OPTION>!;
+ }
+ print '</TD></TR>';
+
+}
+
+#speed_up & speed_down
+my ($speed_up, $speed_down) = ($svc_broadband->speed_up,
+ $svc_broadband->speed_down);
+
+print '<TR><TD ALIGN="right">Download speed</TD><TD>';
+if ( $part_svc->part_svc_column('speed_down')->columnflag eq 'F' ) {
+ print qq!<INPUT TYPE="hidden" NAME="speed_down" VALUE="${speed_down}">! .
+ qq!${speed_down}Kbps</TD></TR>!;
+} else {
+ print qq!<INPUT TYPE="text" NAME="speed_down" SIZE=5 VALUE="${speed_down}">! .
+ qq!Kbps</TD></TR>!;
+}
+
+print '<TR><TD ALIGN="right">Upload speed</TD><TD>';
+if ( $part_svc->part_svc_column('speed_up')->columnflag eq 'F' ) {
+ print qq!<INPUT TYPE="hidden" NAME="speed_up" VALUE="${speed_up}">! .
+ qq!${speed_up}Kbps</TD></TR>!;
+} else {
+ print qq!<INPUT TYPE="text" NAME="speed_up" SIZE=5 VALUE="${speed_up}">! .
+ qq!Kbps</TD></TR>!;
+}
+
+#ip_addr & ip_netmask
+#We're assuming that ip_netmask is fixed if ip_addr is fixed.
+#If it isn't, well, <shudder> what the heck are you doing!?!?
+
+my ($ip_addr, $ip_netmask) = ($svc_broadband->ip_addr,
+ $svc_broadband->ip_netmask);
+
+print '<TR><TD ALIGN="right">IP address/Mask</TD><TD>';
+if ( $part_svc->part_svc_column('ip_addr')->columnflag eq 'F' ) {
+ print qq!<INPUT TYPE="hidden" NAME="ip_addr" VALUE="${ip_addr}">! .
+ qq!<INPUT TYPE="hidden" NAME="ip_netmask" VALUE="${ip_netmask}">! .
+ qq!${ip_addr}/${ip_netmask}</TD></TR>!;
+} else {
+ $ip_addr =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/;
+ print <<END;
+ <INPUT TYPE="text" NAME="ip_addr_a" SIZE="3" MAXLENGTH="3" VALUE="${1}">.
+ <INPUT TYPE="text" NAME="ip_addr_b" SIZE="3" MAXLENGTH="3" VALUE="${2}">.
+ <INPUT TYPE="text" NAME="ip_addr_c" SIZE="3" MAXLENGTH="3" VALUE="${3}">.
+ <INPUT TYPE="text" NAME="ip_addr_d" SIZE="3" MAXLENGTH="3" VALUE="${4}">/
+ <INPUT TYPE="text" NAME="ip_netmask" SIZE="2" MAXLENGTH="2" VALUE="${ip_netmask}">
+</TD></TR>
+<TR><TD COLSPAN="2" WIDTH="300">
+<P><SMALL>Leave the IP address and netmask blank for automatic assignment of a /32 address. Specifing the netmask and not the address will force assignment of a larger block.</SMALL></P>
+</TD></TR>
+END
+}
+
+#mac_addr
+my $mac_addr = $svc_broadband->mac_addr;
+
+unless (( $part_svc->part_svc_column('mac_addr')->columnflag eq 'F' ) and
+ ( $mac_addr eq '' )) {
+ print '<TR><TD ALIGN="right">MAC Address</TD><TD>';
+ if ( $part_svc->part_svc_column('mac_addr')->columnflag eq 'F' ) { #Why?
+ print qq!<INPUT TYPE="hidden" NAME="mac_addr" VALUE="${mac_addr}">! .
+ qq!${mac_addr}</TD></TR>!;
+ } else {
+ #Ewwww
+ $mac_addr =~ /^([a-f0-9]{2}):([a-f0-9]{2}):([a-f0-9]{2}):([a-f0-9]{2}):([a-f0-9]{2}):([a-f0-9]{2})$/i;
+ print <<END;
+ <INPUT TYPE="text" NAME="mac_addr_a" SIZE="2" MACLENGTH="2" VALUE="${1}">:
+ <INPUT TYPE="text" NAME="mac_addr_b" SIZE="2" MACLENGTH="2" VALUE="${2}">:
+ <INPUT TYPE="text" NAME="mac_addr_c" SIZE="2" MACLENGTH="2" VALUE="${3}">:
+ <INPUT TYPE="text" NAME="mac_addr_d" SIZE="2" MACLENGTH="2" VALUE="${4}">:
+ <INPUT TYPE="text" NAME="mac_addr_e" SIZE="2" MACLENGTH="2" VALUE="${5}">:
+ <INPUT TYPE="text" NAME="mac_addr_f" SIZE="2" MACLENGTH="2" VALUE="${6}">
+</TD></TR>
+END
+
+ }
+}
+
+#location
+my $location = $svc_broadband->location;
+
+print '<TR><TD VALIGN="top" ALIGN="right">Location</TD><TD BGCOLOR="#e8e8e8">';
+if ( $part_svc->part_svc_column('location')->columnflag eq 'F' ) {
+ print qq!<PRE>${location}</PRE></TD></TR>!;
+} else {
+ print qq!<TEXTAREA ROWS="4" COLS="30" NAME="location">${location}</TEXTAREA>!;
+}
+
+print '</TABLE><BR><INPUT TYPE="submit" VALUE="Submit">';
+
+print <<END;
+
+ </FORM>
+ </BODY>
+</HTML>
+END
+%>