summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--FS/FS/Schema.pm2
-rw-r--r--FS/FS/part_device.pm15
-rw-r--r--httemplate/browse/part_device.html10
-rw-r--r--httemplate/edit/part_device.html20
-rw-r--r--httemplate/edit/phone_device.html74
-rw-r--r--httemplate/elements/select-mac.html19
-rw-r--r--httemplate/elements/tr-select-mac.html12
-rw-r--r--httemplate/misc/macinventory.cgi25
8 files changed, 174 insertions, 3 deletions
diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm
index fe5f96a..71403b4 100644
--- a/FS/FS/Schema.pm
+++ b/FS/FS/Schema.pm
@@ -3012,7 +3012,7 @@ sub tables_hashref {
'columns' => [
'devicepart', 'serial', '', '', '', '',
'devicename', 'varchar', '', $char_d, '', '',
- #'classnum', #tie to an inventory class?
+ 'inventory_classnum', 'int', 'NULL', '', '', '',
],
'primary_key' => 'devicepart',
'unique' => [ [ 'devicename' ] ], #?
diff --git a/FS/FS/part_device.pm b/FS/FS/part_device.pm
index 4963584..0f840a7 100644
--- a/FS/FS/part_device.pm
+++ b/FS/FS/part_device.pm
@@ -40,6 +40,7 @@ primary key
devicename
+=item inventory_classnum
=back
@@ -103,6 +104,7 @@ sub check {
my $error =
$self->ut_numbern('devicepart')
|| $self->ut_text('devicename')
+ || $self->ut_foreign_keyn('inventory_classnum', 'inventory_class', 'classnum')
;
return $error if $error;
@@ -121,6 +123,19 @@ sub part_export {
qsearch( 'export_device', { 'devicepart' => $self->devicepart } );
}
+=item inventory_class
+
+Returns the inventory class (see L<FS::inventory_class>) for this device,
+if any.
+
+=cut
+
+sub inventory_class {
+ my $self = shift;
+ return '' unless $self->inventory_classnum;
+ qsearchs('inventory_class', { 'classnum' => $self->inventory_classnum });
+}
+
sub process_batch_import {
my $job = shift;
diff --git a/httemplate/browse/part_device.html b/httemplate/browse/part_device.html
index 5c8fde3..69387dd 100644
--- a/httemplate/browse/part_device.html
+++ b/httemplate/browse/part_device.html
@@ -8,12 +8,20 @@
],
'query' => { 'table' => 'part_device', },
'count_query' => 'SELECT COUNT(*) FROM part_device',
- 'header' => [ '#', 'Device type' ],
+ 'header' => [ '#', 'Device type', 'Inventory Class', ],
'fields' => [ 'devicepart',
'devicename',
+ sub {
+ my $part_device = shift;
+ my $inventory_class = $part_device->inventory_class;
+ return $inventory_class->classname
+ if $inventory_class;
+ '';
+ },
],
'links' => [ $link,
$link,
+ '',
],
)
%>
diff --git a/httemplate/edit/part_device.html b/httemplate/edit/part_device.html
index 146070f..1317c8d 100644
--- a/httemplate/edit/part_device.html
+++ b/httemplate/edit/part_device.html
@@ -4,7 +4,9 @@
'labels' => {
'devicepart' => 'Part number',
'devicename' => 'Device name',
+ 'inventory_classnum' => 'Inventory class',
},
+ 'fields' => \@fields,
'viewall_dir' => 'browse',
'html_bottom' => $html_bottom_sub,
)
@@ -20,6 +22,24 @@ my $extra_sql =
);
$extra_sql = $extra_sql ? " WHERE ( $extra_sql ) " : " WHERE 0 = 1 ";
+my @inventory_classnums;
+push @inventory_classnums, '';
+my %inventory_classnum_labels;
+$inventory_classnum_labels{''} = '';
+my @inventory_classes = qsearch('inventory_class', {} );
+foreach my $inventory_class ( @inventory_classes ) {
+ push @inventory_classnums, $inventory_class->classnum;
+ $inventory_classnum_labels{$inventory_class->classnum} = $inventory_class->classname;
+}
+
+my @fields;
+push @fields, 'devicename',
+ { field => 'inventory_classnum',
+ type => 'select',
+ options => \@inventory_classnums,
+ labels => \%inventory_classnum_labels,
+ };
+
my $html_bottom_sub = sub {
my $part_device = shift;
diff --git a/httemplate/edit/phone_device.html b/httemplate/edit/phone_device.html
index a1aa166..c42e714 100644
--- a/httemplate/edit/phone_device.html
+++ b/httemplate/edit/phone_device.html
@@ -10,10 +10,13 @@
'type' => 'select-table',
'table' => 'part_device',
'name_col' => 'devicename',
+ 'onchange' => 'devicepart_changed',
'empty_label' =>'Select device type',
#'hashref' =>{ disabled => '' },
},
- 'mac_addr',
+ { field => 'mac_addr',
+ type => 'select-mac',
+ },
{ 'field' => 'svcnum',
'type' => 'hidden',
},
@@ -24,10 +27,79 @@
my( $cgi, $object ) = @_;
$object->svcnum( $cgi->param('svcnum') );
},
+ 'html_foot' => $html_foot,
)
%>
<%init>
+my @deviceparts_with_inventory;
+my @part_device = qsearch('part_device', {} );
+foreach my $part_device ( @part_device ) {
+ push @deviceparts_with_inventory, $part_device->devicepart
+ if $part_device->inventory_classnum;
+}
+
+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("\",\"",@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;
+ }
+
+ }
+</SCRIPT>";
+
+ $js;
+};
+
# :/ needs agent-virt so you can't futz with arbitrary devices
die "access denied"
diff --git a/httemplate/elements/select-mac.html b/httemplate/elements/select-mac.html
new file mode 100644
index 0000000..3153ca7
--- /dev/null
+++ b/httemplate/elements/select-mac.html
@@ -0,0 +1,19 @@
+<% include('/elements/xmlhttp.html',
+ 'url' => $p.'misc/macinventory.cgi',
+ 'subs' => [ $opt{'prefix'}. 'get_macs' ],
+ )
+%>
+
+<% include( '/elements/input-text.html', %opt, 'type'=>'text' ) %>
+
+<SELECT ID="<% $opt{'prefix'} %>sel_mac_addr" NAME="<% $opt{'prefix'} %>mac_addr"
+ notonChange="<% $opt{'prefix'} %>mac_addr_changed(this); <% $opt{'onchange'} %>"
+ <% $opt{'disabled'} %> STYLE="display: none">
+ <OPTION VALUE="">Select MAC address</OPTION>
+</SELECT>
+
+<%init>
+
+my %opt = @_;
+
+</%init>
diff --git a/httemplate/elements/tr-select-mac.html b/httemplate/elements/tr-select-mac.html
new file mode 100644
index 0000000..026923b
--- /dev/null
+++ b/httemplate/elements/tr-select-mac.html
@@ -0,0 +1,12 @@
+<% include('tr-td-label.html', @_ ) %>
+ <TD>
+ <% include('/elements/select-mac.html', %opt ) %>
+ </TD>
+</TR>
+
+<%init>
+
+my %opt = @_;
+
+</%init>
+
diff --git a/httemplate/misc/macinventory.cgi b/httemplate/misc/macinventory.cgi
new file mode 100644
index 0000000..b07da97
--- /dev/null
+++ b/httemplate/misc/macinventory.cgi
@@ -0,0 +1,25 @@
+<% objToJson(\@macs) %>
+<%init>
+
+# XXX: this should be agent-virtualized / limited
+
+my $devicepart = $cgi->param('arg');
+
+die 'invalid devicepart' unless $devicepart =~ /^\d+$/;
+
+my $part_device = qsearchs('part_device', { 'devicepart' => $devicepart } );
+die "unknown devicepart $devicepart" unless $part_device;
+
+my $inventory_class = $part_device->inventory_class;
+die "devicepart $devicepart has no inventory" unless $inventory_class;
+
+my @inventory_item =
+ qsearch('inventory_item', { 'classnum' => $inventory_class->classnum } );
+
+my @macs;
+
+foreach my $inventory_item ( @inventory_item ) {
+ push @macs, $inventory_item->item;
+}
+
+</%init>