diff options
| author | levinse <levinse> | 2010-11-25 01:46:34 +0000 | 
|---|---|---|
| committer | levinse <levinse> | 2010-11-25 01:46:34 +0000 | 
| commit | 46ef8524cf2e6db7b851967062ce92ffb0773d10 (patch) | |
| tree | 5698390a5c5f95b15997264319f1a1303f97271e | |
| parent | 39289cd1e5a06044aa9a8dc3d2e4d8c9ffb02b11 (diff) | |
ikano.pm initial commit, svc_dsl UI initial commit, and svc_dsl on-going work, RT7111
| -rw-r--r-- | FS/FS/Schema.pm | 14 | ||||
| -rw-r--r-- | FS/FS/part_export/ikano.pm | 102 | ||||
| -rw-r--r-- | FS/FS/part_svc.pm | 11 | ||||
| -rw-r--r-- | FS/FS/svc_dsl.pm | 63 | ||||
| -rw-r--r-- | httemplate/edit/elements/edit.html | 5 | ||||
| -rw-r--r-- | httemplate/edit/elements/svc_Common.html | 7 | ||||
| -rwxr-xr-x | httemplate/edit/part_svc.cgi | 1 | ||||
| -rw-r--r-- | httemplate/edit/process/svc_dsl.html | 10 | ||||
| -rw-r--r-- | httemplate/edit/svc_dsl.cgi | 125 | ||||
| -rw-r--r-- | httemplate/view/elements/svc_Common.html | 10 | ||||
| -rw-r--r-- | httemplate/view/svc_dsl.cgi | 62 | 
11 files changed, 401 insertions, 9 deletions
diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm index 89f3c63dd..39b1ab7d8 100644 --- a/FS/FS/Schema.pm +++ b/FS/FS/Schema.pm @@ -1682,7 +1682,7 @@ sub tables_hashref {        'columns' => [          'qualnum',  'serial',     '',     '', '', '',           'contactnum',    'int',     '',     '', '', '', -	'svctn',     'int', 'NULL',       '', '', '', +	'svctn',     'varchar', 'NULL',       24, '', '',          'svcdb',      'varchar', '', $char_d, '', '',           'vendor_qual_id',      'varchar', 'NULL', $char_d, '', '',           'status',      'char', '', 1, '', '',  @@ -1837,16 +1837,16 @@ sub tables_hashref {        'columns' => [          'svcnum',           'int',    '',        '', '', '',  	'pushed',     'int', 'NULL',       '', '', '', -	'desired_dd',     'int', '',       '', '', '', +	'desired_dd',     'int', 'NULL',       '', '', '',  	'dd',     'int', 'NULL',       '', '', '',          'vendor_order_id',              'varchar', 'NULL', $char_d,  '', '',          'vendor_qual_id',              'varchar', 'NULL', $char_d,  '', '', -        'vendor_order_type',   'char', '',       1,  '', '',  +        'vendor_order_type',   'char', 'NULL',       1,  '', '',           'vendor_order_status',   'char', 'NULL',       1,  '', '',  -        'first',              'varchar', '', $char_d,  '', '', -        'last',              'varchar', '', $char_d,  '', '', +        'first',              'varchar', 'NULL', $char_d,  '', '', +        'last',              'varchar', 'NULL', $char_d,  '', '',          'company',              'varchar', 'NULL', $char_d,  '', '', -	'svctn',     'int', 'NULL',       '', '', '', +	'svctn',     'varchar', 'NULL',       24, '', '',          'loop_type',   'char', 'NULL',       1,  '', '',           'lvp',              'varchar', 'NULL', $char_d,  '', '',          'cktnum',              'varchar', 'NULL', $char_d,  '', '', @@ -1856,7 +1856,7 @@ sub tables_hashref {          'username',              'varchar', 'NULL', $char_d,  '', '',          'password',              'varchar', 'NULL', $char_d,  '', '',          'staticips',             'text', 'NULL', '',  '', '', -        'monitored',   	'char', '',       1,  '', '',  +        'monitored',   	'char', 'NULL',       1,  '', '',   	'last_pull',     'int', 'NULL',       '', '', '',  	'notes',     'text', 'NULL',       '', '', '',        ], diff --git a/FS/FS/part_export/ikano.pm b/FS/FS/part_export/ikano.pm new file mode 100644 index 000000000..c44db64d1 --- /dev/null +++ b/FS/FS/part_export/ikano.pm @@ -0,0 +1,102 @@ +package FS::part_export::ikano; + +use vars qw(@ISA %info); +use Tie::IxHash; +use Date::Format qw( time2str ); +use FS::Record qw(qsearch dbh); +use FS::part_export; +use FS::svc_dsl; + +@ISA = qw(FS::part_export); + +tie my %options, 'Tie::IxHash', +  'keyid'         => { label=>'Ikano keyid' }, +  'username'      => { label=>'Ikano username', +			default => 'admin', +			}, +  'password'      => { label=>'Ikano password' }, +  'check_networks' => { label => 'Check Networks', +		    default => 'ATT,BELLCA', +		    }, +; + +%info = ( +  'svc'     => 'svc_dsl', +  'desc'    => 'Provision DSL to Ikano', +  'options' => \%options, +  'notes'   => <<'END' +Requires installation of +<a href="http://search.cpan.org/dist/Net-Ikano">Net::Ikano</a> from CPAN. +END +); + +sub rebless { shift; } + +sub dsl_pull { +    ''; +} + +sub status_line { +    my($svc_dsl,$date_format,$separator) = (shift,shift,shift); +    my %orderTypes = ( 'N' => 'New', 'X' => 'Cancel', 'C' => 'Change' ); +    my %orderStatus = ( 'N' => 'New', 'P' => 'Pending', 'X' => 'Cancelled', +			'C' => 'Completed', 'E' => 'Error' ); +    my $status = "Ikano ".$orderTypes{$svc_dsl->vendor_order_type}." order #" +	. $svc_dsl->vendor_order_id . " (Status: "  +	. $orderStatus{$svc_dsl->vendor_order_status} . ") $separator "; +    my $monitored = $svc_dsl->monitored eq 'Y' ? 'Yes' : 'No'; +    my $pushed = $svc_dsl->pushed ?  +		time2str("$date_format %k:%M",$svc_dsl->pushed) : "never"; +    my $last_pull = $svc_dsl->last_pull ?  +		time2str("$date_format %k:%M",$svc_dsl->last_pull) : "never"; +    my $ddd = $svc_dsl->desired_dd ? time2str($date_format,$svc_dsl->desired_dd) +				   : ""; +    my $dd = $svc_dsl->dd ? time2str($date_format,$svc_dsl->dd) : ""; +    $status .= "$separator Pushed: $pushed   Monitored: $monitored  Last Pull: "; +    $status .= "$lastpull $separator $separator Desired Due Date: $ddd  "; +    $status .= "Due Date: $dd"; +    return $status;	 +} + +sub ikano_command { +  my( $self, $command, @args ) = @_; + +  eval "use Net::Ikano;"; +  die $@ if $@; + +  my $ikano = Net::Ikano->new( +    'keyid' => $self->option('keyid'), +    'username'  => $self->option('username'), +    'password'  => $self->option('password'), +    #'debug'    => 1, +  ); + +  $ikano->$command(@args); +} + +sub _export_insert { +  my( $self, $svc_dsl ) = (shift, shift); +  ''; +} + +sub _export_replace { +  my( $self, $new, $old ) = (shift, shift, shift); +  ''; +} + +sub _export_delete { +  my( $self, $svc_dsl ) = (shift, shift); +  ''; +} + +sub _export_suspend { +  my( $self, $svc_dsl ) = (shift, shift); +  ''; +} + +sub _export_unsuspend { +  my( $self, $svc_dsl ) = (shift, shift); +  ''; +} + +1; diff --git a/FS/FS/part_svc.pm b/FS/FS/part_svc.pm index 3ed153e0c..164bad079 100644 --- a/FS/FS/part_svc.pm +++ b/FS/FS/part_svc.pm @@ -459,6 +459,17 @@ sub part_export_did {    grep $_->can('get_dids'), $self->part_export;  } +=item part_export_dsl_pull + +Returns a list of any exports (see L<FS::part_export>) for this service that +are capable of pulling/pushing DSL orders. + +=cut + +sub part_export_dsl_pull { +    my $self = shift; +    grep $_->can('dsl_pull'), $self->part_export; +}  =item cust_svc [ PKGPART ]  diff --git a/FS/FS/svc_dsl.pm b/FS/FS/svc_dsl.pm index 0b4b0d1c7..2e84dea63 100644 --- a/FS/FS/svc_dsl.pm +++ b/FS/FS/svc_dsl.pm @@ -155,8 +155,71 @@ points to.  You can ask the object for a copy with the I<hash> method.  # the new method can be inherited from FS::Record, if a table method is defined +sub table_info { +    my %dis1 = ( disable_default=>1, disable_fixed=>1, disable_inventory=>1, disable_select=>1 ); +    my %dis2 = ( disable_inventory=>1, disable_select=>1 ); + +    { +	'name' => 'DSL', +	'sorts' => [ 'svctn' ], +	'display_weight' => 55, +	'cancel_weight' => 75, +	'fields' => { +	    'pushed' => { 	label => 'Pushed',  +				type => 'disabled' }, +	    'desired_dd' => { 	label => 'Desired Due Date', %dis2, }, +	    'dd' => { 		label => 'Due Date', %dis2, }, +	    'vendor_order_id' => { label => 'Vendor Order Id', %dis2, }, +	    'vendor_qual_id' => { label => 'Vendor Qualification Id',  +				type => 'disabled' }, +	    'vendor_order_type' => { label => 'Vendor Order Type', +				    disable_inventory => 1, +				}, +	    'vendor_order_status' => { label => 'Vendor Order Status', +				    disable_inventory => 1, +				    }, +	    'first' => { 	label => 'First Name', %dis2, }, +	    'last' => {  	label => 'Last Name', %dis2, }, +	    'company' => {	label => 'Company Name', %dis2, }, +	    'svctn' => {	label => 'Service Telephone Number', }, +	    'loop_type' => {	label => 'Loop Type', +				    disable_inventory => 1, +			}, +	    'lvp' => {		label => 'Local Voice Provider', +				    disable_inventory => 1, +			}, +	    'cktnum' => {	label => 'Circuit #',	}, +	    'rate_band' => {	label => 'Rate Band', +				    disable_inventory => 1, +			}, +	    'isp_chg' => {	label => 'ISP Changing?',  +				type => 'checkbox', %dis2 }, +	    'isp_prev' => {	label => 'Current or Previous ISP', +				    disable_inventory => 1, +			}, +	    'username' => {	label => 'PPPoE Username', +				type => 'text', +			}, +	    'password' => {	label => 'PPPoE Password', %dis2 }, +	    'staticips' => { 	label => 'Static IPs', %dis1 }, +	    'monitored' => {	label => 'Monitored',  +				type => 'checkbox', %dis2 }, +	    'last_pull' => { 	label => 'Last Pull', type => 'disabled' }, +	    'notes' => { 	label => 'Order Notes', %dis1 }, +	}, +    }; +} +  sub table { 'svc_dsl'; } +sub label { +   my $self = shift; +   return $self->svctn if $self->svctn; +   return $self->username if $self->username; +   return $self->vendor_order_id if $self->vendor_order_id; +   return $self->svcnum; +} +  =item insert  Adds this record to the database.  If there is an error, returns the error, diff --git a/httemplate/edit/elements/edit.html b/httemplate/edit/elements/edit.html index 3d828478f..142d0c3ae 100644 --- a/httemplate/edit/elements/edit.html +++ b/httemplate/edit/elements/edit.html @@ -311,6 +311,11 @@ Example:  %     foreach grep exists($f->{$_}),  %       qw( hashref agent_virt agent_null agent_null_right );  % +%   # fixed +%   $include_common{$_} = $f->{$_} +%     foreach grep exists($f->{$_}), +%       qw( formatted_value ); +%  %   #htmlarea  %   $include_common{$_} = $f->{$_}  %     foreach grep exists($f->{$_}), qw( width height ); diff --git a/httemplate/edit/elements/svc_Common.html b/httemplate/edit/elements/svc_Common.html index e74f44276..2e27f851d 100644 --- a/httemplate/edit/elements/svc_Common.html +++ b/httemplate/edit/elements/svc_Common.html @@ -29,6 +29,13 @@                     die "No part_svc entry!" unless $part_svc;                     label_fixup($part_svc, $opt); +		    +		   if ( my $cb = $opt{'svc_edit_callback'} ) { +                     my $cust_pkg = $pkgnum +                                      ? qsearchs('cust_pkg', {pkgnum=>$pkgnum}) +                                      : ''; #? +                      &{ $cb }( $cgi,$svc_x, $part_svc,$cust_pkg, $fields,$opt); +                    }                   },                   'new_hashref_callback' => sub { diff --git a/httemplate/edit/part_svc.cgi b/httemplate/edit/part_svc.cgi index 50bc79c02..d156ccd0a 100755 --- a/httemplate/edit/part_svc.cgi +++ b/httemplate/edit/part_svc.cgi @@ -16,6 +16,7 @@ Service definitions are the templates for items you offer to your customers.  <UL><LI>svc_acct - Accounts - anything with a username (Mailboxes, PPP accounts, shell accounts, RADIUS entries for broadband, etc.)      <LI>svc_domain - Domains      <LI>svc_cert - Certificates +    <LI>svc_dsl - DSL      <LI>svc_forward - Mail forwarding      <LI>svc_mailinglist - Mailing list      <LI>svc_www - Virtual domain website diff --git a/httemplate/edit/process/svc_dsl.html b/httemplate/edit/process/svc_dsl.html new file mode 100644 index 000000000..627329a00 --- /dev/null +++ b/httemplate/edit/process/svc_dsl.html @@ -0,0 +1,10 @@ +<% include( 'elements/svc_Common.html', +               'table'    => 'svc_dsl', +           ) +%> +<%init> + +die "access denied" +  unless $FS::CurrentUser::CurrentUser->access_right('Provision customer service'); #something else more specific? + +</%init> diff --git a/httemplate/edit/svc_dsl.cgi b/httemplate/edit/svc_dsl.cgi new file mode 100644 index 000000000..3568fbd7d --- /dev/null +++ b/httemplate/edit/svc_dsl.cgi @@ -0,0 +1,125 @@ +<% include( 'elements/svc_Common.html', +            'table'   	=> 'svc_dsl', +	    'fields'	=> \@fields, +	    'svc_new_callback' => $new_cb, +	    'svc_edit_callback' => $edit_cb, +	  ) +%> +<%init> + +die "access denied" +  unless $FS::CurrentUser::CurrentUser->access_right('Provision customer service'); #something else more specific? + +my $conf = new FS::Conf; +my $date_format = $conf->config('date_format') || '%m/%d/%Y'; + +my $ti_fields = FS::svc_dsl->table_info->{'fields'}; + +my @fields = (); +my @uneditable = qw( pushed vendor_qual_id isp_chg isp_prev staticips last_pull notes ); + +my $edit_cb = sub { +    my( $cgi,$svc_x, $part_svc,$cust_pkg, $fields1,$opt) = @_; +    my @exports = $part_svc->part_export_dsl_pull; +    die "more than one DSL-pulling export attached to svcpart ".$part_svc->svcpart +	if ( scalar(@exports) > 1 ); + +    if ( scalar(@exports) == 1 ) { +	my $export = @exports[0];		 +	if($export->exporttype eq 'ikano') { +	    @fields = ( 'password', 'monitored', ); + +	    foreach my $hf ( keys %$ti_fields ) { +		push @fields, { +		    field => $hf, +		    type => 'hidden', +		    value => $svc_x->$hf, +		} unless ( $hf eq 'password' || $hf eq 'monitored' ); +	    } +	} +	else { +	    # XXX +	} +    } +    else { +	# XXX +    } +}; + +my $new_cb = sub { +    my( $cgi,$svc_x, $part_svc,$cust_pkg, $fields1,$opt) = @_; +    my @exports = $part_svc->part_export_dsl_pull; +    die "more than one DSL-pulling export attached to svcpart ".$part_svc->svcpart +	if ( scalar(@exports) > 1 ); + +    if ( scalar(@exports) == 1 ) { +	my $cust_main = $cust_pkg->cust_main; +	my $defsvctn = $cust_main->ship_daytime ? $cust_main->ship_daytime +						: $cust_main->daytime; +	$defsvctn =~ s/[^0-9]//g; + +	@fields = ( +	    { field => 'first', +	      value => $cust_main->ship_first ? $cust_main->ship_first +					      : $cust_main->first, +	    }, +	    { field => 'last', +	      value => $cust_main->ship_last ? $cust_main->ship_last +					     : $cust_main->last, +	    }, +	    { field => 'company', +	      value => $cust_pkg->cust_main->ship_company, +	      value => $cust_main->ship_company ? $cust_main->ship_company +						: $cust_main->company, +	    }, +	    { field => 'svctn', +	      value => $defsvctn, +	    }, +	); + +	my $loop_type = { field => 'loop_type' }; + +	my $export = @exports[0];		 +	if($export->exporttype eq 'ikano') { +	    $cgi->param('vendor_qual_id') =~ /^(\d+)$/  +		or die 'unparsable vendor_qual_id'; +	    my $vendor_qual_id = $1; + +	    die "no start date set on customer package" if !$cust_pkg->start_date; + +	    $loop_type = { field => 'loop_type', +		    type => 'select', +		    options => [ '', '0' ], +		    labels => { '' => 'Line-share', '0', => 'Standalone' }, +		   # onchange => "document.getElementById('svctn').value = ''", +		}; +	    push @fields, { field => 'isp_chg', type => 'checkbox', }; +	    push @fields, 'isp_prev'; +	    push @fields, { field => 'vendor_qual_id', +			    type => 'fixed', +			    value => $vendor_qual_id,  +			  }; +	} +	else { +	    push @fields, 'username'; +	} +	 +	push @fields, 'password'; + +	push @fields, $loop_type; +	     +	push @fields, { field => 'vendor_order_type', +			type => 'hidden', +			value => 'N' }; +	push @fields, { field => 'desired_dd', +			type => 'fixed', +			formatted_value =>  +			    time2str($date_format,$cust_pkg->start_date), +			value => $cust_pkg->start_date,  +		      }; +    } +    else { +	# XXX +    } +}; +</%init> diff --git a/httemplate/view/elements/svc_Common.html b/httemplate/view/elements/svc_Common.html index 618d33eed..25845ddc5 100644 --- a/httemplate/view/elements/svc_Common.html +++ b/httemplate/view/elements/svc_Common.html @@ -52,18 +52,22 @@ function areyousure(href) {  Service #<B><% $svcnum %></B>  % my $url = $opt{'edit_url'} || $p. 'edit/'. $opt{'table'}. '.cgi?';  | <A HREF="<%$url%><%$svcnum%>">Edit this <% $label %></A> + +% unless ( $opt{'disable_unprovision'} ) {  | <A HREF="javascript:areyousure('<%$p.'misc/unprovision.cgi?'.$svcnum%>')">  Unprovision this Service</A>  <BR> +% }  <% ntable("#cccccc") %><TR><TD><% ntable("#cccccc",2) %>  % foreach my $f ( @$fields ) {  % -%   my($field, $type, $value); +%   my($field, $type, $value, $hack_strict_refs);  %   if ( ref($f) ) {  %     $field = $f->{'field'}, -%     $value = $f->{'value'} ? &{ $f->{'value'} }($svc_x) : $svc_x->$field; +%     $hack_strict_refs = \&{ $f->{'value'} } if $f->{'value'}; +%     $value = $f->{'value'} ? &$hack_strict_refs($svc_x) : $svc_x->$field;  %     $type  = $f->{'type'} || 'text',  %   } else {  %     $field = $f; @@ -172,4 +176,6 @@ if ($pkgnum) {    $custnum = '';  } +&{ $opt{'svc_callback'} }( $cgi, $svc_x, $part_svc, $cust_pkg, $fields, \%opt )  +    if $opt{'svc_callback'};  </%init> diff --git a/httemplate/view/svc_dsl.cgi b/httemplate/view/svc_dsl.cgi new file mode 100644 index 000000000..a4b2d4327 --- /dev/null +++ b/httemplate/view/svc_dsl.cgi @@ -0,0 +1,62 @@ +<% include('elements/svc_Common.html', +            'table'     => 'svc_dsl', +            'labels'    => \%labels, +            'fields' => \@fields, +	    'svc_callback' => $svc_cb, +	    'html_foot' => $html_foot, +          ) +%> +<%init> +my $conf = new FS::Conf; +my $date_format = $conf->config('date_format') || '%m/%d/%Y'; + +my $fields = FS::svc_dsl->table_info->{'fields'}; +my %labels = map { $_ =>  ( ref($fields->{$_}) +                             ? $fields->{$_}{'label'} +                             : $fields->{$_} +                         ); +                 } keys %$fields; +my @fields = keys %$fields; + +my $footer; + +my $html_foot = sub { +    return $footer; +}; + +my $svc_cb = sub { +    my( $cgi,$svc_x, $part_svc,$cust_pkg, $fields1,$opt) = @_; + +    my @exports = $part_svc->part_export_dsl_pull; +    die "more than one DSL-pulling export attached to svcpart ".$part_svc->svcpart +	if ( scalar(@exports) > 1 ); +     +    # if no DSL-pulling exports, then just display everything, which is the +    # default behaviour implemented above +    return if ( scalar(@exports) == 0 ); + +    $opt->{'disable_unprovision'} = 1; +    my $exporttype = @exports[0]->exporttype;	 + +    # XXX: AJAX auto-pull +	 +    @fields = qw( svctn first last company username password ); + +    if($exporttype eq 'ikano') { +	push @fields, 'isp_chg'; +	push @fields, 'isp_prev'; +	push @fields, 'staticips'; +    } +    else { +	# XXX +    } +     +    # hack against "can't use string ... as a subroutine ref while 'strict refs' in use" +    my $statusSub = \&{'FS::part_export::'.$exporttype.'::status_line'}; +    my $statusLine = &$statusSub($svc_x,$date_format,"<BR>"); +     +    $footer = "<B>$statusLine</B>"; + +    # XXX: notes +}; +</%init>  | 
