Virtual field merge
authorkhoff <khoff>
Tue, 5 Aug 2003 00:00:18 +0000 (00:00 +0000)
committerkhoff <khoff>
Tue, 5 Aug 2003 00:00:18 +0000 (00:00 +0000)
FS/FS/part_router_field.pm [deleted file]
FS/FS/part_sb_field.pm [deleted file]
FS/FS/router_field.pm [deleted file]
FS/FS/sb_field.pm [deleted file]
httemplate/browse/part_sb_field.cgi [deleted file]
httemplate/edit/part_router_field.cgi [deleted file]
httemplate/edit/part_sb_field.cgi [deleted file]

diff --git a/FS/FS/part_router_field.pm b/FS/FS/part_router_field.pm
deleted file mode 100755 (executable)
index 73ca50f..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-package FS::part_router_field;
-
-use strict;
-use vars qw( @ISA );
-use FS::Record qw( qsearchs );
-use FS::router_field;
-use FS::router;
-
-
-@ISA = qw( FS::Record );
-
-=head1 NAME
-
-FS::part_router_field - Object methods for part_router_field records
-
-=head1 SYNOPSIS
-
-  use FS::part_router_field;
-
-  $record = new FS::part_router_field \%hash;
-  $record = new FS::part_router_field { 'column' => 'value' };
-
-  $error = $record->insert;
-
-  $error = $new_record->replace($old_record);
-
-  $error = $record->delete;
-
-  $error = $record->check;
-
-=head1 DESCRIPTION
-
-A part_router_field represents an xfield definition for routers.  For more
-information on xfields, see L<FS::part_sb_field>.
-
-The following fields are supported:
-
-=over 4
-
-=item routerfieldpart - primary key (assigned automatically)
-
-=item name - name of field
-
-=item length
-
-=item check_block
-
-=item list_source
-
-(See L<FS::part_sb_field> for details on these fields.)
-
-=head1 METHODS
-
-=over 4
-
-=item new HASHREF
-
-Create a new record.  To add the record to the database, see "insert".
-
-=cut
-
-sub table { 'part_router_field'; }
-
-=item insert
-
-Adds this record to the database.  If there is an error, returns the error,
-otherwise returns false.
-
-=item delete
-
-Deletes this record from the database.  If there is an error, returns the
-error, otherwise returns false.
-
-=item replace OLD_RECORD
-
-Replaces OLD_RECORD with this one in the database.  If there is an error,
-returns the error, otherwise returns false.
-
-=item check
-
-Checks all fields to make sure this is a valid record.  If there is an error,
-returns the error, otherwise returns false.  Called by the insert and replace
-methods.
-
-=cut
-
-sub check {
-  my $self = shift;
-  my $error = '';
-
-  $self->name =~ /^([a-z0-9_\-\.]{1,15})$/i
-    or return "Invalid field name for part_router_field";
-
-  ''; #no error
-}
-
-=item list_values
-
-Equivalent to "eval($part_router_field->list_source)".
-
-=cut
-
-sub list_values {
-  my $self = shift;
-  return () unless $self->list_source;
-  my @opts = eval($self->list_source);
-  if($@) { 
-    warn $@;
-    return ();
-  } else { 
-    return @opts;
-  }
-}
-
-=back
-
-=head1 VERSION
-
-$Id: 
-
-=head1 BUGS
-
-Needless duplication of much of FS::part_sb_field, with the result that most of
-the warnings about it apply here also.
-
-=head1 SEE ALSO
-
-FS::svc_broadband, FS::router, FS::router_field,  schema.html
-from the base documentation.
-
-=cut
-
-1;
-
diff --git a/FS/FS/part_sb_field.pm b/FS/FS/part_sb_field.pm
deleted file mode 100755 (executable)
index 8dca946..0000000
+++ /dev/null
@@ -1,267 +0,0 @@
-package FS::part_sb_field;
-
-use strict;
-use vars qw( @ISA );
-use FS::Record qw( qsearchs );
-
-@ISA = qw( FS::Record );
-
-=head1 NAME
-
-FS::part_sb_field - Object methods for part_sb_field records
-
-=head1 SYNOPSIS
-
-  use FS::part_sb_field;
-
-  $record = new FS::part_sb_field \%hash;
-  $record = new FS::part_sb_field { 'column' => 'value' };
-
-  $error = $record->insert;
-
-  $error = $new_record->replace($old_record);
-
-  $error = $record->delete;
-
-  $error = $record->check;
-
-=head1 DESCRIPTION
-
-An FS::part_sb_field object represents an extended field (xfield) definition 
-for svc_broadband's sb_field mechanism (see L<FS::svc_broadband>).  
-FS::part_sb_field inherits from FS::Record.  The following fields are 
-currently supported:
-
-=over 2
-
-=item sbfieldpart - primary key (assigned automatically)
-
-=item name - name of the field
-
-=item svcpart - service type for which this field is available (see L<FS::part_svc>)
-
-=item length - length of the contents of the field (see note #1)
-
-=item check_block - validation routine (see note #2)
-
-=item list_source - enumeration routine (see note #3)
-
-=back
-
-=head1 BACKGROUND
-
-Broadband services, unlike dialup services, are provided over a wide 
-variety of physical media (DSL, wireless, cable modems, digital circuits) 
-and network architectures (Ethernet, PPP, ATM).  For many of these access 
-mechanisms, adding a new customer requires knowledge of some properties 
-of the physical connection (circuit number, the type of CPE in use, etc.).
-It is unreasonable to expect ISPs to alter Freeside's schema (and the 
-associated library and UI code) to make each of these parameters a field in 
-svc_broadband.
-
-Hence sb_field and part_sb_field.  They allow the Freeside administrator to
-define 'extended fields' ('xfields') associated with svc_broadband records.
-These are I<not> processed in any way by Freeside itself; they exist solely for
-use by exports (see L<FS::part_export>) and technical support staff.
-
-For a parallel mechanism (at the per-router level rather than per-service), 
-see L<FS::part_router_field>.
-
-=head1 METHODS
-
-=over 4
-
-=item new HASHREF
-
-Create a new record.  To add the record to the database, see "insert".
-
-=cut
-
-sub table { 'part_sb_field'; }
-
-=item insert
-
-Adds this record to the database.  If there is an error, returns the error,
-otherwise returns false.
-
-=item delete
-
-Deletes this record from the database.  If there is an error, returns the
-error, otherwise returns false.
-
-=item replace OLD_RECORD
-
-Replaces OLD_RECORD with this one in the database.  If there is an error,
-returns the error, otherwise returns false.
-
-=item check
-
-Checks all fields to make sure this is a valid record.  If there is an error,
-returns the error, otherwise returns false.  Called by the insert and replace
-methods.
-
-=cut
-
-sub check {
-  my $self = shift;
-  my $error = '';
-
-  $error = $self->ut_numbern('svcpart');
-  return $error if $error;
-
-  unless (qsearchs('part_svc', { svcpart => $self->svcpart }))
-    { return "Unknown svcpart: " . $self->svcpart;}
-
-  $self->name =~ /^([a-z0-9_\-\.]{1,15})$/i
-    or return "Invalid field name for part_sb_field";
-
-  #How to check input_block, display_block, and check_block?
-
-  ''; #no error
-}
-
-=item list_values
-
-If the I<list_source> field is set, this method eval()s it and 
-returns its output.  If the field is empty, list_values returns 
-an empty list.
-
-Any arguments passed to this method will be received by the list_source 
-code, but this behavior is a fortuitous accident and may be removed in 
-the future.
-
-=cut
-
-sub list_values {
-  my $self = shift;
-  return () unless $self->list_source;
-
-  my @opts = eval($self->list_source);
-  if($@) {
-    warn $@;
-    return ();
-  } else {
-    return @opts;
-  }
-}
-
-=item part_svc
-
-Returns the FS::part_svc object associated with this field definition.
-
-=cut
-
-sub part_svc {
-  my $self = shift;
-  return qsearchs('part_svc', { svcpart => $self->svcpart });
-}
-
-=back
-
-=head1 VERSION
-
-$Id: 
-
-=head1 NOTES
-
-=over
-
-=item 1.
-
-The I<length> field is not enforced.  It provides a hint to UI
-code about how to display the field on a form.  If you want to enforce a
-minimum or maximum length for a field, use a I<check_block>.
-
-=item 2.
-
-The check_block mechanism used here as well as in
-FS::part_router_field allows the user to define validation rules.
-
-When FS::sb_field::check is called, the proposed value of the xfield is
-assigned to $_.  The check_block is then eval()'d and its return value
-captured.  If the return value is false (empty/zero/undef), $_ is then assigned
-back into the field and stored in the database.
-
-Therefore a check_block can do three different things with the value: allow
-it, allow it with a modification, or reject it.  This is very flexible, but
-somewhat dangerous.  Some warnings:
-
-=over 2
-
-=item *
-
-Assume that $_ has had I<no> error checking prior to the
-check_block.  That's what the check_block is for, after all.  It could
-contain I<anything>: evil shell commands in backquotes, 100kb JPEG images,
-the Klez virus, whatever.
-
-=item *
-
-If your check_block modifies the input value, it should probably
-produce a value that wouldn't be modified by going through the same
-check_block again.  (That is, it should map input values into its own
-eigenspace.)  The reason is that if someone calls $new->replace($old),
-where $new and $old contain the same value for the field, they probably
-want the field to keep its old value, not to get transformed by the
-check_block again.  So don't do silly things like '$_++' or
-'tr/A-Za-z/a-zA-Z/'.
-
-=item *
-
-Don't alter the contents of the database.  I<Reading> the database
-is perfectly reasonable, but writing to it is a bad idea.  Remember that
-check() might get called more than once, as described above.
-
-=item *
-
-The check_block probably won't even get called if the user submits
-an I<empty> sb_field.  So at present, you can't set up a default value with
-something like 's/^$/foo/'.  Conversely, don't replace the submitted value
-with an empty string.  It probably will get stored, but might be deleted at
-any time.
-
-=back
-
-=item 3.
-
-The list_source mechanism is a UI hint (like length) to generate
-drop-down or list boxes.  If list_source contains a value, the UI code can
-eval() it and use the results as the options on the list.
-
-Note 'can'.  This is not a substitute for check_block.  The HTML interface
-currently requires that the user pick one of the options on the list
-because that's the way HTML drop-down boxes work, but in the future the UI
-code might add an 'Other (please specify)' option and a text box so that
-the user can enter something else.  Or it might ignore list_source and just
-generate a text box.  Or the interface might be rewritten in MS Access,
-where drop-down boxes have text boxes built in.  Data validation is the job
-of check(), not the front end.
-
-Note also that a list of literals evaluates to itself, so a list_source
-like
-
-C<('Windows', 'MacOS', 'Linux')>
-
-or
-
-C<qw(Windows MacOS Linux)>
-
-means exactly what you'd think.
-
-=head1 BUGS
-
-The lack of any way to do default values.  We might add this as another UI
-hint (since, for the most part, it's the UI's job to figure out which fields
-have had values entered into them).  In fact, there are lots of things we
-should add as UI hints.
-
-Oh, and the documentation is probably full of lies.
-
-=head1 SEE ALSO
-
-FS::svc_broadband, FS::sb_field, schema.html from the base documentation.
-
-=cut
-
-1;
-
diff --git a/FS/FS/router_field.pm b/FS/FS/router_field.pm
deleted file mode 100755 (executable)
index eee21ab..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-package FS::router_field;
-
-use strict;
-use vars qw( @ISA );
-use FS::Record qw( qsearchs );
-use FS::part_router_field;
-use FS::router;
-
-
-@ISA = qw( FS::Record );
-
-=head1 NAME
-
-FS::router_field - Object methods for router_field records
-
-=head1 SYNOPSIS
-
-  use FS::router_field;
-
-  $record = new FS::router_field \%hash;
-  $record = new FS::router_field { 'column' => 'value' };
-
-  $error = $record->insert;
-
-  $error = $new_record->replace($old_record);
-
-  $error = $record->delete;
-
-  $error = $record->check;
-
-=head1 DESCRIPTION
-
-FS::router_field contains values of router xfields.  See FS::part_sb_field 
-for details on the xfield mechanism.
-
-=over 4
-
-=item routerfieldpart - Type of router_field as defined by 
-FS::part_router_field
-
-=item routernum - The FS::router to which this value belongs.
-
-=item value - The contents of the field.
-
-=back
-
-=head1 METHODS
-
-
-=over 4
-
-=item new HASHREF
-
-Create a new record.  To add the record to the database, see "insert".
-
-=cut
-
-sub table { 'router_field'; }
-
-=item insert
-
-Adds this record to the database.  If there is an error, returns the error,
-otherwise returns false.
-
-=item delete
-
-Deletes this record from the database.  If there is an error, returns the
-error, otherwise returns false.
-
-=item replace OLD_RECORD
-
-Replaces OLD_RECORD with this one in the database.  If there is an error,
-returns the error, otherwise returns false.
-
-=item check
-
-Checks all fields to make sure this is a valid record.  If there is an error,
-returns the error, otherwise returns false.  Called by the insert and replace
-methods.
-
-=cut
-
-sub check {
-  my $self = shift;
-
-  return "routernum must be defined" unless $self->routernum;
-  return "routerfieldpart must be defined" unless $self->routerfieldpart;
-
-  my $part_router_field = $self->part_router_field;
-  $_ = $self->value;
-
-  my $check_block = $part_router_field->check_block;
-  if ($check_block) {
-    $@ = '';
-    my $error = (eval($check_block) or $@);
-    return $error if $error;
-    $self->setfield('value' => $_);
-  }
-
-  ''; #no error
-}
-
-=item part_router_field
-
-Returns a reference to the FS:part_router_field that defines this 
-FS::router_field
-
-=cut
-
-sub part_router_field {
-  my $self = shift;
-
-  return qsearchs('part_router_field', 
-    { routerfieldpart => $self->routerfieldpart });
-}
-
-=item router
-
-Returns a reference to the FS::router to which this FS::router_field 
-belongs.
-
-=cut
-
-sub router {
-  my $self = shift;
-
-  return qsearchs('router', { routernum => $self->routernum });
-}
-
-=back
-
-=head1 VERSION
-
-$Id: 
-
-=head1 BUGS
-
-=head1 SEE ALSO
-
-FS::svc_broadband, FS::router, FS::router_block, FS::router_field,  
-schema.html from the base documentation.
-
-=cut
-
-1;
-
diff --git a/FS/FS/sb_field.pm b/FS/FS/sb_field.pm
deleted file mode 100755 (executable)
index d4eb378..0000000
+++ /dev/null
@@ -1,148 +0,0 @@
-package FS::sb_field;
-
-use strict;
-use vars qw( @ISA );
-use FS::Record qw( qsearchs );
-use FS::part_sb_field;
-
-use UNIVERSAL qw( can );
-
-@ISA = qw( FS::Record );
-
-=head1 NAME
-
-FS::sb_field - Object methods for sb_field records
-
-=head1 SYNOPSIS
-
-  use FS::sb_field;
-
-  $record = new FS::sb_field \%hash;
-  $record = new FS::sb_field { 'column' => 'value' };
-
-  $error = $record->insert;
-
-  $error = $new_record->replace($old_record);
-
-  $error = $record->delete;
-
-  $error = $record->check;
-
-=head1 DESCRIPTION
-
-See L<FS::part_sb_field> for details on this table's mission in life.
-FS::sb_field contains the actual values of the xfields defined in
-part_sb_field.
-
-The following fields are supported:
-
-=over 4
-
-=item sbfieldpart - Type of sb_field as defined by FS::part_sb_field
-
-=item svcnum - The svc_broadband to which this value belongs.
-
-=item value - The contents of the field.
-
-=back
-
-=head1 METHODS
-
-=over 4
-
-=item new HASHREF
-
-Create a new record.  To add the record to the database, see L<"insert">.
-
-=cut
-
-sub table { 'sb_field'; }
-
-=item insert
-
-Adds this record to the database.  If there is an error, returns the error,
-otherwise returns false.
-
-=item delete
-
-Deletes this record from the database.  If there is an error, returns the
-error, otherwise returns false.
-
-=item replace OLD_RECORD
-
-Replaces OLD_RECORD with this one in the database.  If there is an error,
-returns the error, otherwise returns false.
-
-=item check
-
-Checks the value against the check_block of the corresponding part_sb_field.
-Returns whatever the check_block returned (unless the check_block dies, in 
-which case check returns the die message).  Therefore, if the check_block 
-wants to allow the value to be stored, it must return false.  See 
-L<FS::part_sb_field> for details.
-
-=cut
-
-sub check {
-  my $self = shift;
-
-  return "svcnum must be defined" unless $self->svcnum;
-  return "sbfieldpart must be defined" unless $self->sbfieldpart;
-
-  my $part_sb_field = $self->part_sb_field;
-
-  $_ = $self->value;
-
-  my $check_block = $self->part_sb_field->check_block;
-  if ($check_block) {
-    $@ = '';
-    my $error = (eval($check_block) or $@); # treat fatal errors as errors
-    return $error if $error;
-    $self->setfield('value' => $_);
-  }
-
-  ''; #no error
-}
-
-=item part_sb_field
-
-Returns a reference to the FS::part_sb_field that defines this FS::sb_field.
-
-=cut
-
-sub part_sb_field {
-  my $self = shift;
-
-  return qsearchs('part_sb_field', { sbfieldpart => $self->sbfieldpart });
-}
-
-=back
-
-=item svc_broadband
-
-Returns a reference to the FS::svc_broadband to which this value is attached.
-Nobody's ever going to use this function, but here it is anyway.
-
-=cut
-
-sub svc_broadband {
-  my $self = shift;
-
-  return qsearchs('svc_broadband', { svcnum => $self->svcnum });
-}
-
-=head1 VERSION
-
-$Id: 
-
-=head1 BUGS
-
-=head1 SEE ALSO
-
-L<FS::svc_broadband>, schema.html
-from the base documentation.
-
-=cut
-
-1;
-
diff --git a/httemplate/browse/part_sb_field.cgi b/httemplate/browse/part_sb_field.cgi
deleted file mode 100644 (file)
index 4c9641e..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-<%= header('svc_broadband extended fields', menubar('Main Menu'   => $p)) %>
-<%
-
-my @psf = qsearch('part_sb_field', {});
-my $block;
-my $p2 = popurl(2);
-
-%>
-
-<% if ($cgi->param('error')) { %>
-   <FONT SIZE="+1" COLOR="#ff0000">Error: <%=$cgi->param('error')%></FONT>
-   <BR><BR>
-<% } %>
-
-<A HREF="<%=$p2%>edit/part_sb_field.cgi"><I>Add a new field</I></A><BR><BR>
-
-<%=table()%>
-<TH><TD>Field name</TD><TD>Service type</TD></TH>
-<% foreach $psf (sort {$a->name cmp $b->name} @psf) { %>
-  <TR>
-    <TD></TD>
-    <TD>
-      <A HREF="<%=$p2%>edit/part_sb_field.cgi?<%=$psf->sbfieldpart%>">
-        <%=$psf->name%></A></TD>
-    <TD><%=$psf->part_svc->svc%></TD>
-  </TR>
-<% } %>
-</TABLE>
-</BODY>
-</HTML>
-
diff --git a/httemplate/edit/part_router_field.cgi b/httemplate/edit/part_router_field.cgi
deleted file mode 100644 (file)
index 02962b1..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-<!-- mason kludge -->
-<%
-my ($routerfieldpart, $part_router_field);
-
-if ( $cgi->param('error') ) {
-  $part_router_field = new FS::part_router_field ( {
-    map { $_, scalar($cgi->param($_)) } fields('part_router_field')});
-  $routerfieldpart = $part_router_field->routerfieldpart;
-} else {
-  my($query) = $cgi->keywords;
-  if ( $query =~ /^(\d+)$/ ) { #editing
-    $routerfieldpart=$1;
-    $part_router_field=qsearchs('part_router_field',
-        {'routerfieldpart' => $routerfieldpart})
-      or die "Unknown routerfieldpart!";
-  
-  } else { #adding
-    $part_router_field = new FS::part_router_field({});
-  }
-}
-my $action = $part_router_field->routerfieldpart ? 'Edit' : 'Add';
-
-my $p1 = popurl(1);
-print header("$action Router Extended Field Definition",
-             menubar('Main Menu' => $p,
-                     'View all Extended Fields' => $p. 'browse/generic.cgi?part_router_field')
-            );
-
-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_router_field">
-<INPUT TYPE="hidden" NAME="routerfieldpart" VALUE="<%=
-  $routerfieldpart%>">
-Field #<B><%=$routerfieldpart or "(NEW)"%></B><BR><BR>
-
-<%=ntable("#cccccc",2)%>
-  <TR>
-    <TD ALIGN="right">Name</TD>
-    <TD><INPUT TYPE="text" NAME="name" MAXLENGTH=15 VALUE="<%=
-    $part_router_field->name%>"></TD>
-  </TR>
-  <TR>
-    <TD ALIGN="right">Length</TD>
-    <TD><INPUT TYPE="text" NAME="length" MAXLENGTH=4 VALUE="<%=
-    $part_router_field->length%>"></TD>
-  </TR>
-  <TR>
-    <TD ALIGN="right">check_block</TD>
-    <TD><TEXTAREA COLS="20" ROWS="4" NAME="check_block"><%=
-    $part_router_field->check_block%></TEXTAREA></TD>
-  </TR>
-  <TR>
-    <TD ALIGN="right">list_source</TD>
-    <TD><TEXTAREA COLS="20" ROWS="4" NAME="list_source"><%=
-    $part_router_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/part_sb_field.cgi b/httemplate/edit/part_sb_field.cgi
deleted file mode 100644 (file)
index 9e0cc9e..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-<!-- mason kludge -->
-<%
-my ($sbfieldpart, $part_sb_field);
-
-if ( $cgi->param('error') ) {
-  $part_sb_field = new FS::part_sb_field ( {
-    map { $_, scalar($cgi->param($_)) } fields('part_sb_field')});
-  $sbfieldpart = $part_sb_field->sbfieldpart;
-} else {
-  my($query) = $cgi->keywords;
-  if ( $query =~ /^(\d+)$/ ) { #editing
-    $sbfieldpart=$1;
-    $part_sb_field=qsearchs('part_sb_field',
-        {'sbfieldpart' => $sbfieldpart})
-      or die "Unknown sbfieldpart!";
-  
-  } else { #adding
-    $part_sb_field = new FS::part_sb_field({});
-  }
-}
-my $action = $part_sb_field->sbfieldpart ? 'Edit' : 'Add';
-
-my $p1 = popurl(1);
-print header("$action svc_broadband Extended 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_sb_field">
-<INPUT TYPE="hidden" NAME="redirect_ok" 
-    VALUE="<%=popurl(2)%>browse/part_sb_field.cgi">
-<INPUT TYPE="hidden" NAME="sbfieldpart" VALUE="<%=
-  $sbfieldpart%>">
-Field #<B><%=$sbfieldpart or "(NEW)"%></B><BR><BR>
-
-<%=ntable("#cccccc",2)%>
-  <TR>
-    <TD ALIGN="right">Name</TD>
-    <TD><INPUT TYPE="text" NAME="name" MAXLENGTH=15 VALUE="<%=
-    $part_sb_field->name%>"></TD>
-  </TR>
-  <TR>
-    <TD ALIGN="right">Length</TD>
-    <TD><INPUT TYPE="text" NAME="length" MAXLENGTH=4 VALUE="<%=
-    $part_sb_field->length%>"></TD>
-  </TR>
-  <TR>
-    <TD ALIGN="right">Service</TD>
-    <TD><SELECT SIZE=1 NAME="svcpart"><%
-      foreach my $part_svc (qsearch('part_svc', {svcdb => 'svc_broadband'})) {
-        %><OPTION VALUE="<%=$part_svc->svcpart%>"<%=
-         ($part_svc->svcpart == $part_sb_field->svcpart) ? ' SELECTED' : ''%>">
-         <%=$part_svc->svc%>
-      <% } %>
-      </SELECT></TD>
-  <TR>
-    <TD ALIGN="right">check_block</TD>
-    <TD><TEXTAREA COLS="20" ROWS="4" NAME="check_block"><%=
-    $part_sb_field->check_block%></TEXTAREA></TD>
-  </TR>
-  <TR>
-    <TD ALIGN="right">list_source</TD>
-    <TD><TEXTAREA COLS="20" ROWS="4" NAME="list_source"><%=
-    $part_sb_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>