diff options
| author | Ivan Kohler <ivan@freeside.biz> | 2014-01-24 00:39:40 -0800 | 
|---|---|---|
| committer | Ivan Kohler <ivan@freeside.biz> | 2014-01-24 00:39:40 -0800 | 
| commit | f3ac48703be75c0e2aec161487057eafeb8fc74f (patch) | |
| tree | fd3bc7402cf055bbdccd86927532283cde51b562 | |
| parent | 960c55002469c33ea9b0a949ad473a705e1b6cf9 (diff) | |
svc_pbx devices, for RT#24968
| -rw-r--r-- | FS/FS.pm | 2 | ||||
| -rw-r--r-- | FS/FS/MAC_Mixin.pm (renamed from FS/FS/svc_MAC_Mixin.pm) | 2 | ||||
| -rw-r--r-- | FS/FS/Mason.pm | 2 | ||||
| -rw-r--r-- | FS/FS/Schema.pm | 39 | ||||
| -rw-r--r-- | FS/FS/dsl_device.pm | 2 | ||||
| -rw-r--r-- | FS/FS/extension_device.pm | 110 | ||||
| -rw-r--r-- | FS/FS/pbx_device.pm | 114 | ||||
| -rw-r--r-- | FS/FS/phone_device.pm | 2 | ||||
| -rw-r--r-- | FS/FS/svc_External_Common.pm | 22 | ||||
| -rwxr-xr-x | FS/FS/svc_broadband.pm | 2 | ||||
| -rw-r--r-- | FS/FS/svc_cable.pm | 2 | ||||
| -rw-r--r-- | FS/FS/svc_pbx.pm | 2 | ||||
| -rw-r--r-- | FS/FS/svc_video.pm | 2 | ||||
| -rw-r--r-- | FS/MANIFEST | 4 | ||||
| -rw-r--r-- | FS/t/extension_device.t | 5 | ||||
| -rw-r--r-- | FS/t/pbx_device.t | 5 | ||||
| -rw-r--r-- | httemplate/edit/elements/device_Common.html | 110 | ||||
| -rw-r--r-- | httemplate/edit/pbx_device.html | 4 | ||||
| -rw-r--r-- | httemplate/edit/process/elements/device_Common.html | 27 | ||||
| -rw-r--r-- | httemplate/edit/process/pbx_device.html | 3 | ||||
| -rwxr-xr-x | httemplate/misc/delete-pbx_device.html | 23 | ||||
| -rw-r--r-- | httemplate/view/elements/svc_devices.html | 8 | 
22 files changed, 462 insertions, 30 deletions
@@ -206,6 +206,8 @@ L<FS::svc_pbx> - PBX service class  L<FS::pbx_extension> - PBX extension class +L<FS::pbx_device> - PBX device class +  L<FS::svc_cert> - Certificate service class  L<FS::svc_dish> - Dish network service class diff --git a/FS/FS/svc_MAC_Mixin.pm b/FS/FS/MAC_Mixin.pm index 737a8e83f..8715995c1 100644 --- a/FS/FS/svc_MAC_Mixin.pm +++ b/FS/FS/MAC_Mixin.pm @@ -1,4 +1,4 @@ -package FS::svc_MAC_Mixin; +package FS::MAC_Mixin;  use strict;  #use FS::Record qw(qsearch); diff --git a/FS/FS/Mason.pm b/FS/FS/Mason.pm index 7d783769e..a4eac45aa 100644 --- a/FS/FS/Mason.pm +++ b/FS/FS/Mason.pm @@ -369,6 +369,8 @@ if ( -e $addl_handler_use_file ) {    use FS::part_pkg_usageprice;    use FS::cust_pkg_usageprice;    use FS::pbx_extension; +  use FS::pbx_device; +  use FS::extension_device;    # Sammath Naur    if ( $FS::Mason::addl_handler_use ) { diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm index 2300c07fc..0447892d2 100644 --- a/FS/FS/Schema.pm +++ b/FS/FS/Schema.pm @@ -5676,6 +5676,45 @@ sub tables_hashref {                          ],      }, +    'pbx_device' => { +      'columns' => [ +        'devicenum', 'serial',     '', '', '', '', +        'devicepart',   'int',     '', '', '', '', +        'svcnum',       'int',     '', '', '', '',  +        'mac_addr', 'varchar', 'NULL', 12, '', '',  +      ], +      'primary_key'  => 'devicenum', +      'unique'       => [ [ 'mac_addr' ], ], +      'index'        => [ [ 'devicepart' ], [ 'svcnum' ], ], +      'foreign_keys' => [ +                          { columns    => [ 'devicepart' ], +                            table      => 'part_device', +                          }, +                          { columns    => [ 'svcnum' ], +                            table      => 'svc_pbx', +                          }, +                        ], +    }, + +    'extension_device' => { +      'columns' => [ +        'extensiondevicenum', 'serial', '', '', '', '', +        'extensionnum',          'int', '', '', '', '', +        'devicenum',             'int', '', '', '', '', +      ], +      'primary_key'  => 'extensiondevicenum', +      'unique'       => [ [ 'extensionnum', 'devicenum' ] ], +      'index'        => [],#both?  which way do we need to query? +      'foreign_keys' => [ +                          { columns  => [ 'extensionnum' ], +                            table    => 'pbx_extension', +                          }, +                          { columns  => [ 'devicenum' ], +                            table    => 'pbx_device', +                          }, +                        ], +    }, +      'svc_mailinglist' => { #svc_group?        'columns' => [          'svcnum',            'int',     '',            '', '', '',  diff --git a/FS/FS/dsl_device.pm b/FS/FS/dsl_device.pm index 39e8c3468..1e86d44f5 100644 --- a/FS/FS/dsl_device.pm +++ b/FS/FS/dsl_device.pm @@ -1,5 +1,5 @@  package FS::dsl_device; -use base qw( FS::Record ); +use base qw( FS::MAC_Mixin FS::Record );  use strict; diff --git a/FS/FS/extension_device.pm b/FS/FS/extension_device.pm new file mode 100644 index 000000000..23d881e64 --- /dev/null +++ b/FS/FS/extension_device.pm @@ -0,0 +1,110 @@ +package FS::extension_device; +use base qw( FS::Record ); + +use strict; +#use FS::Record qw( qsearch qsearchs ); + +=head1 NAME + +FS::extension_device - Object methods for extension_device records + +=head1 SYNOPSIS + +  use FS::extension_device; + +  $record = new FS::extension_device \%hash; +  $record = new FS::extension_device { 'column' => 'value' }; + +  $error = $record->insert; + +  $error = $new_record->replace($old_record); + +  $error = $record->delete; + +  $error = $record->check; + +=head1 DESCRIPTION + +An FS::extension_device object represents a PBX extension association with a  +specific PBX device (SIP phone or ATA).  FS::extension_device inherits from +FS::Record.  The following fields are currently supported: + +=over 4 + +=item extensiondevicenum + +primary key + +=item extensionnum + +extensionnum + +=item devicenum + +devicenum + + +=back + +=head1 METHODS + +=over 4 + +=item new HASHREF + +Creates a new record.  To add the record 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 + +sub table { 'extension_device'; } + +=item insert + +Adds this record to the database.  If there is an error, returns the error, +otherwise returns false. + +=item delete + +Delete this record from the database. + +=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. + +=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->ut_numbern('extensiondevicenum') +    || $self->ut_foreign_keyn('extensionnum', 'pbx_extension', 'extensionnum') +    || $self->ut_foreign_keyn('devicenum', 'pbx_device', 'devicenum') +  ; +  return $error if $error; + +  $self->SUPER::check; +} + +=back + +=head1 BUGS + +=head1 SEE ALSO + +L<FS::Record> + +=cut + +1; + diff --git a/FS/FS/pbx_device.pm b/FS/FS/pbx_device.pm new file mode 100644 index 000000000..ec1c3b90e --- /dev/null +++ b/FS/FS/pbx_device.pm @@ -0,0 +1,114 @@ +package FS::pbx_device; +use base qw( FS::MAC_Mixin FS::Record ); + +use strict; +#use FS::Record qw( qsearch qsearchs ); + +=head1 NAME + +FS::pbx_device - Object methods for pbx_device records + +=head1 SYNOPSIS + +  use FS::pbx_device; + +  $record = new FS::pbx_device \%hash; +  $record = new FS::pbx_device { 'column' => 'value' }; + +  $error = $record->insert; + +  $error = $new_record->replace($old_record); + +  $error = $record->delete; + +  $error = $record->check; + +=head1 DESCRIPTION + +An FS::pbx_device object represents a specific customer phone device, such +as a SIP phone or ATA.  FS::pbx_device inherits from FS::Record.  The following fields are currently supported: + +=over 4 + +=item devicenum + +primary key + +=item devicepart + +devicepart + +=item svcnum + +svcnum + +=item mac_addr + +mac_addr + + +=back + +=head1 METHODS + +=over 4 + +=item new HASHREF + +Creates a new record.  To add the record 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 + +sub table { 'pbx_device'; } + +=item insert + +Adds this record to the database.  If there is an error, returns the error, +otherwise returns false. + +=item delete + +Delete this record from the database. + +=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. + +=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->ut_numbern('devicenum') +    || $self->ut_foreign_key('devicepart', 'part_device', 'devicepart') +    || $self->ut_foreign_key('svcnum', 'svc_pbx', 'svcnum') +    || $self->ut_mac_addr('mac_addr') +  ; +  return $error if $error; + +  $self->SUPER::check; +} + +=back + +=head1 BUGS + +=head1 SEE ALSO + +L<FS::Record> + +=cut + +1; + diff --git a/FS/FS/phone_device.pm b/FS/FS/phone_device.pm index d5f80a2c5..b891bb294 100644 --- a/FS/FS/phone_device.pm +++ b/FS/FS/phone_device.pm @@ -1,5 +1,5 @@  package FS::phone_device; -use base qw( FS::Record ); +use base qw( FS::MAC_Mixin FS::Record );  use strict;  use Scalar::Util qw( blessed ); diff --git a/FS/FS/svc_External_Common.pm b/FS/FS/svc_External_Common.pm index a5805aafd..32fe7f3db 100644 --- a/FS/FS/svc_External_Common.pm +++ b/FS/FS/svc_External_Common.pm @@ -8,28 +8,12 @@ use FS::svc_Common;  =head1 NAME -FS::svc_external - Object methods for svc_external records +FS::svc_External_Common - Base class for svc_X classes which track external databases  =head1 SYNOPSIS -  use FS::svc_external; - -  $record = new FS::svc_external \%hash; -  $record = new FS::svc_external { 'column' => 'value' }; - -  $error = $record->insert; - -  $error = $new_record->replace($old_record); - -  $error = $record->delete; - -  $error = $record->check; - -  $error = $record->suspend; - -  $error = $record->unsuspend; - -  $error = $record->cancel; +  package FS::svc_newservice; +  use base qw( FS::svc_External_Common );  =head1 DESCRIPTION diff --git a/FS/FS/svc_broadband.pm b/FS/FS/svc_broadband.pm index b9c89cef7..ce50a0c3b 100755 --- a/FS/FS/svc_broadband.pm +++ b/FS/FS/svc_broadband.pm @@ -3,7 +3,7 @@ use base qw(    FS::svc_Radius_Mixin    FS::svc_Tower_Mixin    FS::svc_IP_Mixin  -  FS::svc_MAC_Mixin +  FS::MAC_Mixin    FS::svc_Common    ); diff --git a/FS/FS/svc_cable.pm b/FS/FS/svc_cable.pm index 3a1dc5ae9..12a1dbba5 100644 --- a/FS/FS/svc_cable.pm +++ b/FS/FS/svc_cable.pm @@ -1,5 +1,5 @@  package FS::svc_cable; -use base qw( FS::svc_MAC_Mixin +use base qw( FS::MAC_Mixin               FS::svc_Common             ); #FS::device_Common diff --git a/FS/FS/svc_pbx.pm b/FS/FS/svc_pbx.pm index 7899621b2..d35b3a22c 100644 --- a/FS/FS/svc_pbx.pm +++ b/FS/FS/svc_pbx.pm @@ -1,5 +1,5 @@  package FS::svc_pbx; -use base qw( FS::o2m_Common FS::svc_External_Common ); +use base qw( FS::o2m_Common FS::device_Common FS::svc_External_Common );  use strict;  use Tie::IxHash; diff --git a/FS/FS/svc_video.pm b/FS/FS/svc_video.pm index a6ff13628..999b87c66 100644 --- a/FS/FS/svc_video.pm +++ b/FS/FS/svc_video.pm @@ -1,5 +1,5 @@  package FS::svc_video; -use base qw( FS::svc_MAC_Mixin FS::svc_Common ); +use base qw( FS::MAC_Mixin FS::svc_Common );  use strict;  use Tie::IxHash; diff --git a/FS/MANIFEST b/FS/MANIFEST index f2f1e3984..bedc26cf2 100644 --- a/FS/MANIFEST +++ b/FS/MANIFEST @@ -751,3 +751,7 @@ FS/cust_pkg_usageprice.pm  t/cust_pkg_usageprice.t  FS/pbx_extension.pm  t/pbx_extension.t +FS/pbx_device.pm +t/pbx_device.t +FS/extension_device.pm +t/extension_device.t diff --git a/FS/t/extension_device.t b/FS/t/extension_device.t new file mode 100644 index 000000000..5927a17bf --- /dev/null +++ b/FS/t/extension_device.t @@ -0,0 +1,5 @@ +BEGIN { $| = 1; print "1..1\n" } +END {print "not ok 1\n" unless $loaded;} +use FS::extension_device; +$loaded=1; +print "ok 1\n"; diff --git a/FS/t/pbx_device.t b/FS/t/pbx_device.t new file mode 100644 index 000000000..9cd549942 --- /dev/null +++ b/FS/t/pbx_device.t @@ -0,0 +1,5 @@ +BEGIN { $| = 1; print "1..1\n" } +END {print "not ok 1\n" unless $loaded;} +use FS::pbx_device; +$loaded=1; +print "ok 1\n"; diff --git a/httemplate/edit/elements/device_Common.html b/httemplate/edit/elements/device_Common.html new file mode 100644 index 000000000..ab8135784 --- /dev/null +++ b/httemplate/edit/elements/device_Common.html @@ -0,0 +1,110 @@ +<& edit.html, +     'labels' => {  +                   'devicenum'  => 'Device', +                   'devicepart' => 'Device type', +                   'mac_addr'   => 'MAC address', +                 }, +     'fields' => [ { 'field'    => 'devicepart', +                     'type'     => 'select-table', +                     'table'    => 'part_device', +                     'name_col' => 'devicename', +                     'onchange' => 'devicepart_changed', +                     'empty_label' =>'Select device type', +                     #'hashref'        =>{ disabled => '' }, +                   }, +                   { field => 'mac_addr', +                     type => 'select-mac', +                   }, +                   { 'field' => 'svcnum', +                     'type'  => 'hidden', +                   }, +                 ], +     'menubar' => [], #disable viewall +     #'viewall_dir' => 'browse', +     'new_callback' => sub { +                         my( $cgi, $object ) = @_; +                         $object->svcnum( $cgi->param('svcnum') ); +                       }, +     'html_foot' => $html_foot, +     %opt, +&> +<%init> + +my %opt = @_; + +my @deviceparts_with_inventory = +  map $_->devicepart, +    qsearch({ 'table'     => 'part_device', +              'extra_sql' => 'WHERE inventory_classnum IS NOT NULL', +           }); + +my $html_foot = sub { +    my $js = " +<SCRIPT TYPE=\"text/javascript\"> + +  function opt(what,value,text) { +    var optionName = new Option(text, value, false, false); +    var length = what.length; +    what.options[length] = optionName; +  } + +    function devicepart_changed(what){ +	 +	var macsel = document.getElementById('sel_mac_addr'); +	var mac = document.getElementById('mac_addr'); +	 +	function update_macs(macs) { +	    for ( var i = macsel.length; i >= 0; i-- ) +	      macsel.options[i] = null; +	     +	    var macArray = eval('(' + macs + ')' ); +	    if(macArray.length == 0)  +		opt(macsel,'','No MAC addresses found in inventory for this device type'); +	    else +		opt(macsel,'','Select MAC address'); + +	    for ( var i = 0; i < macArray.length; i++ ) { +		opt(macsel,macArray[i],macArray[i]); +	    } + +	} + +	var devicepart = what.options[what.selectedIndex].value; + +	var deviceparts_with_inventory = new Array("; +$js .= join(',', map qq("$_"), @deviceparts_with_inventory); +$js .= "); + +	var hasInventory = false; +	for ( i = 0; i < deviceparts_with_inventory.length; i++ ) { +	    if ( deviceparts_with_inventory[i] == devicepart )  +		hasInventory = true; +	} +	 + +	if(hasInventory) { // do the AJAX thing, disable text field +	    macsel.style.display = 'inline'; +	    mac.style.display = 'none'; +	    mac.value = ''; +	    get_macs( devicepart, update_macs ); +	} else { // clear & display text field only, clear/hide select +	    mac.style.display = 'inline'; +	    macsel.style.display = 'none'; +	    macsel.selectedIndex = 0; +	} + +    } + +    devicepart_changed(document.getElementById('devicepart')); +</SCRIPT>"; + +  $js; +}; + +# :/  needs agent-virt so you can't futz with arbitrary devices + +die "access denied" +  unless $FS::CurrentUser::CurrentUser->access_right('Provision customer service'); #something else more specific? + + +</%init> diff --git a/httemplate/edit/pbx_device.html b/httemplate/edit/pbx_device.html new file mode 100644 index 000000000..457ec7121 --- /dev/null +++ b/httemplate/edit/pbx_device.html @@ -0,0 +1,4 @@ +<& elements/device_Common.html, +     'name'  => 'PBX device', +     'table' => 'pbx_device', +&> diff --git a/httemplate/edit/process/elements/device_Common.html b/httemplate/edit/process/elements/device_Common.html new file mode 100644 index 000000000..7b6f2cd78 --- /dev/null +++ b/httemplate/edit/process/elements/device_Common.html @@ -0,0 +1,27 @@ +<& process.html, +     'redirect' => sub { +       my( $cgi, $X_device ) = @_; +       popurl(3)."view/$svc_table.cgi?". +         'svcnum='. $X_device->svcnum. +         ';devicenum='; +     }, +     %opt, +&> +<%init> + +my %opt = @_; + +warn my $table = $opt{table}; +( my $svc_table = $table ) =~ s/_device//; +$svc_table = "svc_$svc_table"; + +if($cgi->param('sel_mac_addr') && !$cgi->param('mac_addr')) { +    $cgi->param('mac_addr',$cgi->param('sel_mac_addr')); +} + +# :/  needs agent-virt so you can't futz with arbitrary devices + +die "access denied" +  unless $FS::CurrentUser::CurrentUser->access_right('Provision customer service'); #something else more specific? + +</%init> diff --git a/httemplate/edit/process/pbx_device.html b/httemplate/edit/process/pbx_device.html new file mode 100644 index 000000000..664a9e715 --- /dev/null +++ b/httemplate/edit/process/pbx_device.html @@ -0,0 +1,3 @@ +<& elements/device_Common.html, +     'table' => 'pbx_device', +&> diff --git a/httemplate/misc/delete-pbx_device.html b/httemplate/misc/delete-pbx_device.html new file mode 100755 index 000000000..7540d2f9f --- /dev/null +++ b/httemplate/misc/delete-pbx_device.html @@ -0,0 +1,23 @@ +% if ( $error ) { +%   errorpage($error); +% } else { +<% $cgi->redirect($p. "view/svc_pbx.cgi?". $svcnum) %> +% } +<%init> + +# :/  needs agent-virt so you can't futz with arbitrary devices + +die "access denied" +  unless $FS::CurrentUser::CurrentUser->access_right('Provision customer service'); #something else more specific? + +#untaint devicenum +my($query) = $cgi->keywords; +$query =~ /^(\d+)$/ || die "Illegal devicenum"; +my $devicenum = $1; + +my $pbx_device = qsearchs('pbx_device', { 'devicenum' => $devicenum } ); +my $svcnum = $pbx_device->svcnum; + +my $error = $pbx_device->delete; + +</%init> diff --git a/httemplate/view/elements/svc_devices.html b/httemplate/view/elements/svc_devices.html index 9458c922c..c9f5eda78 100644 --- a/httemplate/view/elements/svc_devices.html +++ b/httemplate/view/elements/svc_devices.html @@ -15,7 +15,7 @@  %if ( @devices || $num_part_device || $table eq 'dsl_device' ) {  %  my $svcnum = $svc_x->svcnum; -   Devices +   <FONT CLASS="fsinnerbox-title">Devices</FONT>     (<A HREF="<%$p%>edit/<%$table%>.html?svcnum=<%$svcnum%>">Add device</A>)     <BR> @@ -30,7 +30,7 @@       <& /elements/table-grid.html &>         <TR> -%        if ( $table eq 'phone_device' || $table eq 'cable_device' ) { +%        if ( $table ne 'dsl_device' ) { # ( $table eq 'phone_device' || $table eq 'cable_device' || $table eq 'pbx_device' ) {             <TH CLASS="grid" BGCOLOR="#cccccc">Type</TH>  %        }           <TH CLASS="grid" BGCOLOR="#cccccc">MAC Addr</TH> @@ -62,7 +62,7 @@  %         if ( $table eq 'phone_device' || $svc_x->isa('FS::device_Common') ) {              <% $td %><% $device->part_device->devicename |h %></TD>  %         } -          <% $td %><% $device->mac_addr %></TD> +          <% $td %><% $device->mac_addr_pretty %></TD>            <% $td %><% $export_links %></TD>            <% $td %>(  %           unless ( $opt{'no_edit'} ) { @@ -85,7 +85,7 @@ my $table = $opt{'table'}; #part_device, dsl_device  my $svc_x = $opt{'svc_x'};  my $num_part_device = 0; -if ( $table eq 'phone_device' || $table eq 'cable_device' ) { +if ( $table ne 'dsl_device' ) { # ( $table eq 'phone_device' || $table eq 'cable_device' || $table eq 'pbx_device' ) {    my $sth = dbh->prepare("SELECT COUNT(*) FROM part_device")                              #WHERE disabled = '' OR disabled IS NULL;");      or die dbh->errstr;  | 
