diff options
author | Ivan Kohler <ivan@freeside.biz> | 2012-05-13 22:16:37 -0700 |
---|---|---|
committer | Ivan Kohler <ivan@freeside.biz> | 2012-05-13 22:16:37 -0700 |
commit | 8d7cd4b2bd99cc1a711d81b55a1652d31eda4df5 (patch) | |
tree | f742c8f30a6724b4cf429a3247a2c9e075b668f2 | |
parent | 6a66ab1163bfcd6f46df00aa474d013530a1e13c (diff) |
service def classes, to support corecom portal, RT#17617
-rw-r--r-- | FS/FS.pm | 2 | ||||
-rw-r--r-- | FS/FS/Schema.pm | 12 | ||||
-rw-r--r-- | FS/FS/part_svc.pm | 6 | ||||
-rw-r--r-- | FS/FS/part_svc_class.pm | 126 | ||||
-rw-r--r-- | FS/MANIFEST | 2 | ||||
-rw-r--r-- | FS/t/part_svc_class.t | 5 | ||||
-rw-r--r-- | httemplate/browse/part_svc_class.html | 34 | ||||
-rw-r--r-- | httemplate/docs/part_svc-table.html | 63 | ||||
-rwxr-xr-x | httemplate/edit/part_svc.cgi | 131 | ||||
-rw-r--r-- | httemplate/edit/part_svc_class.html | 6 | ||||
-rw-r--r-- | httemplate/edit/process/part_svc_class.html | 11 | ||||
-rw-r--r-- | httemplate/elements/menu.html | 1 | ||||
-rw-r--r-- | httemplate/elements/select-part_svc_class.html | 22 | ||||
-rw-r--r-- | httemplate/elements/tr-select-part_svc_class.html | 27 |
14 files changed, 369 insertions, 79 deletions
@@ -214,6 +214,8 @@ L<FS::inventory_item> - Inventory items L<FS::part_svc> - Service definition class +L<FS::part_svc_class> - Service class class + L<FS::part_svc_column> - Column constraint class L<FS::export_svc> - Class linking service definitions (see L<FS::part_svc>) diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm index 843e2108b..e3f34a4fd 100644 --- a/FS/FS/Schema.pm +++ b/FS/FS/Schema.pm @@ -1850,6 +1850,7 @@ sub tables_hashref { 'disabled', 'char', 'NULL', 1, '', '', 'preserve', 'char', 'NULL', 1, '', '', 'selfservice_access', 'varchar', 'NULL', $char_d, '', '', + 'classnum', 'int', 'NULL', '', '', '', ], 'primary_key' => 'svcpart', 'unique' => [], @@ -1870,6 +1871,17 @@ sub tables_hashref { 'index' => [ [ 'svcpart' ] ], }, + 'part_svc_class' => { + 'columns' => [ + 'classnum', 'serial', '', '', '', '', + 'classname', 'varchar', '', $char_d, '', '', + 'disabled', 'char', 'NULL', 1, '', '', + ], + 'primary_key' => 'classnum', + 'unique' => [], + 'index' => [ ['disabled'] ], + }, + #(this should be renamed to part_pop) 'svc_acct_pop' => { 'columns' => [ diff --git a/FS/FS/part_svc.pm b/FS/FS/part_svc.pm index 7e592bf72..20b80c684 100644 --- a/FS/FS/part_svc.pm +++ b/FS/FS/part_svc.pm @@ -9,6 +9,7 @@ use FS::part_svc_column; use FS::part_export; use FS::export_svc; use FS::cust_svc; +use FS::part_svc_class; @ISA = qw(FS::Record); @@ -51,6 +52,8 @@ FS::Record. The following fields are currently supported: =item svcdb - table used for this service. See L<FS::svc_acct>, L<FS::svc_domain>, and L<FS::svc_forward>, among others. +=item classnum - Optional service class (see L<FS::svc_class>) + =item disabled - Disabled flag, empty or `Y' =item preserve - Preserve after cancellation, empty or 'Y' @@ -387,6 +390,7 @@ sub check { || $self->ut_enum('disabled', [ '', 'Y' ] ) || $self->ut_enum('preserve', [ '', 'Y' ] ) || $self->ut_enum('selfservice_access', [ '', 'hidden', 'readonly' ] ) + || $self->ut_foreign_keyn('classnum', 'part_svc_class', 'classnum' ) ; return $error if $error; @@ -712,7 +716,7 @@ sub process { my $job = shift; my $param = thaw(decode_base64(shift)); - warn Dumper($param) if $DEBUG; + warn Dumper($param);# if $DEBUG; my $old = qsearchs('part_svc', { 'svcpart' => $param->{'svcpart'} }) if $param->{'svcpart'}; diff --git a/FS/FS/part_svc_class.pm b/FS/FS/part_svc_class.pm new file mode 100644 index 000000000..d1c991582 --- /dev/null +++ b/FS/FS/part_svc_class.pm @@ -0,0 +1,126 @@ +package FS::part_svc_class; +use base qw( FS::class_Common ); + +use strict; +use FS::Record; # qw( qsearch qsearchs ); + +=head1 NAME + +FS::part_svc_class - Object methods for part_svc_class records + +=head1 SYNOPSIS + + use FS::part_svc_class; + + $record = new FS::part_svc_class \%hash; + $record = new FS::part_svc_class { 'column' => 'value' }; + + $error = $record->insert; + + $error = $new_record->replace($old_record); + + $error = $record->delete; + + $error = $record->check; + +=head1 DESCRIPTION + +An FS::part_svc_class object represents a service class. FS::part_svc_class +inherits from FS::Record. The following fields are currently supported: + +=over 4 + +=item classnum + +primary key + +=item classname + +classname + +=item disabled + +disabled + + +=back + +=head1 METHODS + +=over 4 + +=item new HASHREF + +Creates a new service class. To add the service class to the database, see L<"insert">. + +Note that this stores the hash reference, not a distinct copy of the hash it +points to. You can ask the object for a copy with the I<hash> method. + +=cut + +# the new method can be inherited from FS::Record, if a table method is defined + +sub table { 'part_svc_class'; } + +=item insert + +Adds this record to the database. If there is an error, returns the error, +otherwise returns false. + +=cut + +# the insert method can be inherited from FS::Record + +=item delete + +Delete this record from the database. + +=cut + +# the delete method can be inherited from FS::Record + +=item replace OLD_RECORD + +Replaces the OLD_RECORD with this one in the database. If there is an error, +returns the error, otherwise returns false. + +=cut + +# the replace method can be inherited from FS::Record + +=item check + +Checks all fields to make sure this is a valid service class. If there is +an error, returns the error, otherwise returns false. Called by the insert +and replace methods. + +=cut + +# the check method should currently be supplied - FS::Record contains some +# data checking routines + +sub check { + my $self = shift; + + my $error = + $self->ut_numbern('classnum') + || $self->ut_text('classname') + || $self->ut_enum('disabled', [ '', 'Y' ] ) + ; + return $error if $error; + + $self->SUPER::check; +} + +=back + +=head1 BUGS + +=head1 SEE ALSO + +L<FS::Record>, schema.html from the base documentation. + +=cut + +1; + diff --git a/FS/MANIFEST b/FS/MANIFEST index 91711d340..8bb4eee6d 100644 --- a/FS/MANIFEST +++ b/FS/MANIFEST @@ -638,3 +638,5 @@ FS/sales.pm t/sales.t FS/access_groupsales.pm t/access_groupsales.t +FS/part_svc_class.pm +t/part_svc_class.t diff --git a/FS/t/part_svc_class.t b/FS/t/part_svc_class.t new file mode 100644 index 000000000..e838c0b30 --- /dev/null +++ b/FS/t/part_svc_class.t @@ -0,0 +1,5 @@ +BEGIN { $| = 1; print "1..1\n" } +END {print "not ok 1\n" unless $loaded;} +use FS::part_svc_class; +$loaded=1; +print "ok 1\n"; diff --git a/httemplate/browse/part_svc_class.html b/httemplate/browse/part_svc_class.html new file mode 100644 index 000000000..73bd60305 --- /dev/null +++ b/httemplate/browse/part_svc_class.html @@ -0,0 +1,34 @@ +<% include( 'elements/browse.html', + 'title' => 'Service classes', + 'html_init' => $html_init, + 'name' => 'service classes', + 'disableable' => 1, + 'disabled_statuspos' => 1, + 'query' => { 'table' => 'part_svc_class', + 'hashref' => {}, + 'order_by' => 'ORDER BY classnum', + }, + 'count_query' => $count_query, + 'header' => $header, + 'fields' => $fields, + 'links' => $links, + ) +%> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +my $html_init = + 'Service classes are user-defined, informational types for services.<BR><BR>'. + qq!<A HREF="${p}edit/part_svc_class.html"><I>Add a service class</I></A><BR><BR>!; + +my $count_query = 'SELECT COUNT(*) FROM part_svc_class'; + +my $link = [ $p.'edit/part_svc_class.html?', 'classnum' ]; + +my $header = [ '#', 'Class' ]; +my $fields = [ 'classnum', 'classname' ]; +my $links = [ $link, $link ]; + +</%init> diff --git a/httemplate/docs/part_svc-table.html b/httemplate/docs/part_svc-table.html new file mode 100644 index 000000000..48841f550 --- /dev/null +++ b/httemplate/docs/part_svc-table.html @@ -0,0 +1,63 @@ +<& /elements/header-popup.html &> + +<TABLE> + <TR> + <TH ALIGN="left">Generic</TH> + <TH ALIGN="left">Access</TH> + <TH ALIGN="left">Telephony</TH> +<!-- <TH>Hosting</TH> + <TH>Colocation</TH> +--> + </TR> + <TR> + <TD VALIGN="top"> + <UL STYLE="margin:0"> + <LI><B>svc_acct</B>: Accounts - anything with a username (mailbox, shell, RADIUS, etc.) + <LI><B>svc_hardware</B>: Equipment supplied to customers + <LI><B>svc_external</B>: Externally-tracked service + </UL> + </TD> + <TD VALIGN="top"> + <UL STYLE="margin:0"> + <LI><B>svc_dsl</B>: DSL + <LI><B>svc_broadband</B>: Wireless broadband + <LI><B>svc_dish</B>: DISH Network + </UL> + </TD> + <TD VALIGN="top"> + <UL STYLE="margin:0"> + <LI><B>svc_phone</B>: Customer phone number + <LI><B>svc_pbx</B>: Customer PBX + </UL> + </TD> + </TR> +</TABLE> +<BR> +<TABLE> + <TR> + <TH ALIGN="left">Hosting</TH> + <TH ALIGN="left">Colocation</TH> + </TR> + <TD VALIGN="top"> + <UL STYLE="margin:0"> + <LI><B>svc_domain</B>: Domain + <LI><B>svc_cert</B>: Certificate + <LI><B>svc_forward</B>: Mail forwarding + <LI><B>svc_mailinglist</B>: Mailing list + <LI><B>svc_www</B>: Virtual domain website + </UL> + </TD> + <TD VALIGN="top"> + <UL STYLE="margin:0"> + <LI><B>svc_port</B>: Customer router/switch port + </UL> + </TD> + </TR> +<TABLE> +<!-- <LI>svc_charge - One-time charges (Partially unimplemented) + <LI>svc_wo - Work orders (Partially unimplemented) +--> + +</BODY> +</HTML> + diff --git a/httemplate/edit/part_svc.cgi b/httemplate/edit/part_svc.cgi index fae896154..4bd083798 100755 --- a/httemplate/edit/part_svc.cgi +++ b/httemplate/edit/part_svc.cgi @@ -1,17 +1,27 @@ -<% include('/elements/header.html', "$action Service Definition", +<& /elements/header.html, "$action Service Definition", menubar('View all service definitions' => "${p}browse/part_svc.cgi"), #" onLoad=\"visualize()\"" - ) -%> +&> + +<& /elements/init_overlib.html &> + +<BR> <FORM NAME="dummy"> - Service Part #<% $part_svc->svcpart ? $part_svc->svcpart : "(NEW)" %> -<BR><BR> -Service <INPUT TYPE="text" NAME="svc" VALUE="<% $hashref->{svc} %>"><BR> +<FONT CLASS="fsinnerbox-title">Service Part #<% $part_svc->svcpart ? $part_svc->svcpart : "(NEW)" %></FONT> +<TABLE CLASS="fsinnerbox"> +<TR> + <TD ALIGN="right">Service</TD> + <TD><INPUT TYPE="text" NAME="svc" VALUE="<% $hashref->{svc} %>"></TD> +<TR> + +<& /elements/tr-select-part_svc_class.html, curr_value=>$hashref->{classnum} &> -Self-service access: -<SELECT NAME="selfservice_access"> +<TR> + <TD ALIGN="right">Self-service access</TD> + <TD> + <SELECT NAME="selfservice_access"> % tie my %selfservice_access, 'Tie::IxHash', #false laziness w/browse/part_svc % '' => 'Yes', % 'hidden' => 'Hidden', @@ -22,12 +32,22 @@ Self-service access: <% $_ eq $hashref->{'selfservice_access'} ? 'SELECTED' : '' %> ><% $selfservice_access{$_} %> % } -</SELECT><BR> + </SELECT> + </TD> +</TR> -<INPUT TYPE="checkbox" NAME="disabled" VALUE="Y"<% $hashref->{disabled} eq 'Y' ? ' CHECKED' : '' %>> Disable new orders<BR> -<INPUT TYPE="checkbox" NAME="preserve" VALUE="Y"<% $hashref->{'preserve'} eq 'Y' ? ' CHECKED' : '' %>> Preserve this service on package cancellation<BR> +<TR> + <TD ALIGN="right">Disable new orders</TD> + <TD><INPUT TYPE="checkbox" NAME="disabled" VALUE="Y"<% $hashref->{disabled} eq 'Y' ? ' CHECKED' : '' %>></TD> +</TR> +<TR> + <TD ALIGN="right">Preserve this service on package cancellation</TD> + <TD><INPUT TYPE="checkbox" NAME="preserve" VALUE="Y"<% $hashref->{'preserve'} eq 'Y' ? ' CHECKED' : '' %>> </TD> +</TR> + +</TABLE> <INPUT TYPE="hidden" NAME="svcpart" VALUE="<% $hashref->{svcpart} %>"> @@ -76,6 +96,18 @@ Self-service access: % ? ( $hashref->{svcdb} ) % : FS::part_svc->svc_tables(); % +% my $help = ''; +% unless ( $hashref->{svcpart} ) { +% $help = ' '. +% include('/elements/popup_link.html', +% 'action' => $p.'docs/part_svc-table.html', +% 'label' => 'help', +% 'actionlabel' => 'Service table help', +% 'width' => 763, +% #'height' => 400, +% ); +% } +% % tie my %svcdb, 'Tie::IxHash', map { $_=>$_ } grep dbdef->table($_), @dbs; % my $widget = new HTML::Widgets::SelectLayers( % #'selected_layer' => $p_svcdb, @@ -84,15 +116,16 @@ Self-service access: % 'form_name' => 'dummy', % #'form_action' => 'process/part_svc.cgi', % 'form_action' => 'part_svc.cgi', #self -% 'form_text' => [ qw( svc svcpart ) ], -% 'form_select' => [ 'selfservice_access' ], -% 'form_checkbox' => [ 'disabled', 'preserve' ], +% 'form_elements' => [qw( svc svcpart classnum selfservice_access +% disabled preserve +% )], +% 'html_between' => $help, % 'layer_callback' => sub { % my $layer = shift; % % my $html = qq!<INPUT TYPE="hidden" NAME="svcdb" VALUE="$layer">!; % -% $html .= $svcdb_info; +% #$html .= $svcdb_info; % % my $columns = 3; % my $count = 0; @@ -267,6 +300,7 @@ Self-service access: % % $html .= include('/elements/select-table.html', % 'element_name' => "${layer}__${field}_classnum", +% 'id' => "${layer}__${field}_classnum", % 'element_etc' => ( $is_inv % ? $disabled % : $nodisplay @@ -349,6 +383,7 @@ Self-service access: % $html .= include('/elements/select-hardware_class.html', % 'curr_value' => $value, % 'element_name' => "${layer}__${field}_classnum", +% 'id' => "${layer}__${field}_classnum", % 'element_etc' => $flag ne 'H' && $nodisplay, % 'empty_label' => 'Select hardware class', % ); @@ -382,7 +417,8 @@ Self-service access: % % $html .= include('/elements/progress-init.html', % $layer, #form name -% [ qw(svc svcpart selfservice_access disabled preserve +% [ qw(svc svcpart classnum selfservice_access +% disabled preserve % exportnum), % @fields ], % 'process/part_svc.cgi', @@ -401,9 +437,8 @@ Self-service access: % % }, % ); -% -% +<BR> Table <% $widget->html %> <% include('/elements/footer.html') %> @@ -451,66 +486,6 @@ my %communigate_fields = ( #'svc_cert' => { map { $_=>1 } qw( ) }, ); -my $svcdb_info = ' -<TABLE> - <TR> - <TH ALIGN="left">Generic</TH> - <TH ALIGN="left">Access</TH> - <TH ALIGN="left">Telephony</TH> -<!-- <TH>Hosting</TH> - <TH>Colocation</TH> ---> - </TR> - <TR> - <TD VALIGN="top"> - <UL STYLE="margin:0"> - <LI><B>svc_acct</B>: Accounts - anything with a username (mailbox, shell, RADIUS, etc.) - <LI><B>svc_hardware</B>: Equipment supplied to customers - <LI><B>svc_external</B>: Externally-tracked service - </UL> - </TD> - <TD VALIGN="top"> - <UL STYLE="margin:0"> - <LI><B>svc_dsl</B>: DSL - <LI><B>svc_broadband</B>: Wireless broadband - <LI><B>svc_dish</B>: DISH Network - </UL> - </TD> - <TD VALIGN="top"> - <UL STYLE="margin:0"> - <LI><B>svc_phone</B>: Customer phone number - <LI><B>svc_pbx</B>: Customer PBX - </UL> - </TD> - </TR> -</TABLE> -<BR> -<TABLE> - <TR> - <TH ALIGN="left">Hosting</TH> - <TH ALIGN="left">Colocation</TH> - </TR> - <TD VALIGN="top"> - <UL STYLE="margin:0"> - <LI><B>svc_domain</B>: Domain - <LI><B>svc_cert</B>: Certificate - <LI><B>svc_forward</B>: Mail forwarding - <LI><B>svc_mailinglist</B>: Mailing list - <LI><B>svc_www</B>: Virtual domain website - </UL> - </TD> - <TD VALIGN="top"> - <UL STYLE="margin:0"> - <LI><B>svc_port</B>: Customer router/switch port - </UL> - </TD> - </TR> -<TABLE> -<!-- <LI>svc_charge - One-time charges (Partially unimplemented) - <LI>svc_wo - Work orders (Partially unimplemented) ---> -'; - my $mod_info = ' For the selected table, you can give fields default or fixed (unchangable) values, or select an inventory class to manually or automatically fill in diff --git a/httemplate/edit/part_svc_class.html b/httemplate/edit/part_svc_class.html new file mode 100644 index 000000000..0d9a00727 --- /dev/null +++ b/httemplate/edit/part_svc_class.html @@ -0,0 +1,6 @@ +<% include( 'elements/class_Common.html', + 'name' => 'Service class', + 'table' => 'part_svc_class', + 'nocat' => 1, + ) +%> diff --git a/httemplate/edit/process/part_svc_class.html b/httemplate/edit/process/part_svc_class.html new file mode 100644 index 000000000..16165dd18 --- /dev/null +++ b/httemplate/edit/process/part_svc_class.html @@ -0,0 +1,11 @@ +<% include( 'elements/process.html', + 'table' => 'part_svc_class', + 'viewall_dir' => 'browse', + ) +%> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +</%init> diff --git a/httemplate/elements/menu.html b/httemplate/elements/menu.html index 42feb7b96..fcc17eaa2 100644 --- a/httemplate/elements/menu.html +++ b/httemplate/elements/menu.html @@ -457,6 +457,7 @@ tie my %config_radius, 'Tie::IxHash', tie my %config_export_svc, 'Tie::IxHash', (); if ( $curuser->access_right('Configuration') ) { $config_export_svc{'Service definitions'} = [ $fsurl.'browse/part_svc.cgi', 'Services are items you offer to your customers' ]; + $config_export_svc{'Service classes'} = [ $fsurl.'browse/part_svc_class.html', 'Services classes are user-defined, informational types for services' ]; $config_export_svc{'Provisioning exports'} = [ $fsurl.'browse/part_export.cgi', 'Provisioning services to external machines, databases and APIs' ]; } $config_export_svc{'Dialup'} = [ \%config_dialup, '' ] diff --git a/httemplate/elements/select-part_svc_class.html b/httemplate/elements/select-part_svc_class.html new file mode 100644 index 000000000..280e3e17d --- /dev/null +++ b/httemplate/elements/select-part_svc_class.html @@ -0,0 +1,22 @@ +<% include( '/elements/select-table.html', + 'table' => 'part_svc_class', + 'name_col' => 'classname', + 'value' => $classnum, + 'empty_label' => '(none)', + 'hashref' => \%hash, + %opt, + ) +%> +<%init> + +my %opt = @_; +my $classnum = $opt{'curr_value'} || $opt{'value'}; + +my %hash = (); +$hash{'disabled'} = '' unless $opt{'showdisabled'}; + + +$opt{'records'} = delete $opt{'part_svc_class'} + if $opt{'part_svc_class'}; + +</%init> diff --git a/httemplate/elements/tr-select-part_svc_class.html b/httemplate/elements/tr-select-part_svc_class.html new file mode 100644 index 000000000..2f4b09381 --- /dev/null +++ b/httemplate/elements/tr-select-part_svc_class.html @@ -0,0 +1,27 @@ +% if ( scalar(@{ $opt{'part_svc_class'} }) == 0 ) { + + <INPUT TYPE="hidden" NAME="<% $opt{'element_name'} || $opt{'field'} || 'classnum' %>" VALUE=""> + +% } else { + + <TR> + <TD ALIGN="right"><% $opt{'label'} || 'Service class' %></TD> + <TD> + <% include( '/elements/select-part_svc_class.html', + 'curr_value' => $classnum, + %opt + ) + %> + </TD> + </TR> + +% } + +<%init> + +my %opt = @_; +my $classnum = $opt{'curr_value'} || $opt{'value'}; + +$opt{'part_svc_class'} ||= [ qsearch( 'part_svc_class', { disabled=>'' } ) ]; + +</%init> |