Merge branch 'master' of git.freeside.biz:/home/git/freeside
authorIvan Kohler <ivan@freeside.biz>
Fri, 19 Apr 2013 03:39:27 +0000 (20:39 -0700)
committerIvan Kohler <ivan@freeside.biz>
Fri, 19 Apr 2013 03:39:27 +0000 (20:39 -0700)
FS/FS/Schema.pm
FS/FS/svc_broadband.pm
httemplate/edit/svc_broadband.cgi
httemplate/elements/search-svc_broadband.html [new file with mode: 0644]
httemplate/elements/tr-search-svc_broadband.html [new file with mode: 0644]
httemplate/misc/xmlhttp-svc_broadband-search.cgi [new file with mode: 0644]
httemplate/view/svc_broadband.cgi

index 9f68a41..eb73ccb 100644 (file)
@@ -2909,22 +2909,28 @@ sub tables_hashref {
 
     'svc_broadband' => {
       'columns' => [
-        'svcnum',                  'int',     '',      '', '', '', 
-        'description',         'varchar', 'NULL', $char_d, '', '', 
-        'routernum',               'int', 'NULL',      '', '', '',
-        'blocknum',                'int', 'NULL',      '', '', '', 
-        'sectornum',               'int', 'NULL',      '', '', '',
-        'speed_up',                'int', 'NULL',      '', '', '', 
-        'speed_down',              'int', 'NULL',      '', '', '', 
-        'ip_addr',             'varchar', 'NULL',      15, '', '', 
-        'mac_addr',            'varchar', 'NULL',      12, '', '', 
-        'authkey',             'varchar', 'NULL',      32, '', '', 
-        'latitude',            'decimal', 'NULL',  '10,7', '', '', 
-        'longitude',           'decimal', 'NULL',  '10,7', '', '', 
-        'altitude',            'decimal', 'NULL',      '', '', '', 
-        'vlan_profile',        'varchar', 'NULL', $char_d, '', '', 
-        'performance_profile', 'varchar', 'NULL', $char_d, '', '',
-        'plan_id',             'varchar', 'NULL', $char_d, '', '',
+        'svcnum',                  'int',     '',        '', '', '', 
+        'description',         'varchar', 'NULL',   $char_d, '', '', 
+        'routernum',               'int', 'NULL',        '', '', '',
+        'blocknum',                'int', 'NULL',        '', '', '', 
+        'sectornum',               'int', 'NULL',        '', '', '',
+        'speed_up',                'int', 'NULL',        '', '', '', 
+        'speed_down',              'int', 'NULL',        '', '', '', 
+        'ip_addr',             'varchar', 'NULL',        15, '', '', 
+        'mac_addr',            'varchar', 'NULL',        12, '', '', 
+        'authkey',             'varchar', 'NULL',        32, '', '', 
+        'latitude',            'decimal', 'NULL',    '10,7', '', '', 
+        'longitude',           'decimal', 'NULL',    '10,7', '', '', 
+        'altitude',            'decimal', 'NULL',        '', '', '', 
+        'vlan_profile',        'varchar', 'NULL',   $char_d, '', '', 
+        'performance_profile', 'varchar', 'NULL',   $char_d, '', '',
+        'plan_id',             'varchar', 'NULL',   $char_d, '', '',
+        'radio_serialnum',     'varchar', 'NULL',   $char_d, '', '',
+        'radio_location',      'varchar', 'NULL', 2*$char_d, '', '',
+        'poe_location',        'varchar', 'NULL', 2*$char_d, '', '',
+        'rssi',                    'int', 'NULL',        '', '', '',
+        'suid',                    'int', 'NULL',        '', '', '',
+        'shared_svcnum',           'int', 'NULL',        '', '', '',
       ],
       'primary_key' => 'svcnum',
       'unique'      => [ [ 'ip_addr' ], [ 'mac_addr' ] ],
index 7c396ec..002aa55 100755 (executable)
@@ -134,6 +134,15 @@ sub table_info {
                          disable_inventory => 1,
                          multiple => 1,
                        },
+      'radio_serialnum' => 'Radio Serial Number',
+      'radio_location'  => 'Radio Location',
+      'poe_location'    => 'POE Location',
+      'rssi'            => 'RSSI',
+      'suid'            => 'SUID',
+      'shared_svcnum'   => { label             => 'Shared Service',
+                             type              => 'search-svc_broadband',
+                             disable_inventory => 1,
+                           },
     },
   };
 }
@@ -225,15 +234,31 @@ sub search_sql {
   my( $class, $string ) = @_;
   if ( $string =~ /^(\d{1,3}\.){3}\d{1,3}$/ ) {
     $class->search_sql_field('ip_addr', $string );
-  }elsif ( $string =~ /^([a-fA-F0-9]{12})$/ ) {
+  } elsif ( $string =~ /^([a-fA-F0-9]{12})$/ ) {
     $class->search_sql_field('mac_addr', uc($string));
-  }elsif ( $string =~ /^(([a-fA-F0-9]{1,2}:){5}([a-fA-F0-9]{1,2}))$/ ) {
+  } elsif ( $string =~ /^(([a-fA-F0-9]{1,2}:){5}([a-fA-F0-9]{1,2}))$/ ) {
     $class->search_sql_field('mac_addr', uc("$2$3$4$5$6$7") );
+  } elsif ( $string =~ /^(\d+)$/ ) {
+    my $table = $class->table;
+    "$table.svcnum = $1";
   } else {
     '1 = 0'; #false
   }
 }
 
+=item smart_search STRING
+
+=cut
+
+sub smart_search {
+  my( $class, $string ) = @_;
+  qsearch({
+    'table'     => $class->table, #'svc_broadband',
+    'hashref'   => {},
+    'extra_sql' => 'WHERE '. $class->search_sql($string),
+  });
+}
+
 =item label
 
 Returns the IP address.
@@ -330,6 +355,12 @@ sub check {
     || $self->ut_sfloatn('altitude')
     || $self->ut_textn('vlan_profile')
     || $self->ut_textn('plan_id')
+    || $self->ut_alphan('radio_serialnum')
+    || $self->ut_textn('radio_location')
+    || $self->ut_textn('poe_location')
+    || $self->ut_snumbern('rssi')
+    || $self->ut_numbern('suid')
+    || $self->ut_foreign_keyn('shared_svcnum', 'svc_broadband', 'svcnum')
   ;
   return $error if $error;
 
index 0d4b989..1b85460 100644 (file)
@@ -104,8 +104,12 @@ my @fields = (
   { field=>'sectornum', type=>'select-tower_sector', },
   { field=>'routernum', type=>'select-router_block_ip' },
   { field=>'mac_addr' , type=>'input-mac_addr' },
-    qw( latitude longitude altitude vlan_profile 
-    performance_profile authkey plan_id )
+  qw(
+      latitude longitude altitude
+      radio_serialnum radio_location poe_location rssi suid
+    ),
+  { field=>'shared_svcnum', type=>'search-svc_broadband', },
+  qw( vlan_profile performance_profile authkey plan_id ),
 );
 
 if ( $conf->exists('svc_broadband-radius') ) {
diff --git a/httemplate/elements/search-svc_broadband.html b/httemplate/elements/search-svc_broadband.html
new file mode 100644 (file)
index 0000000..d835161
--- /dev/null
@@ -0,0 +1,204 @@
+<%doc>
+
+Example:
+
+  include( '/elements/search-svc_broadband.html,
+             'field'       => 'svcnum',
+             #slightly deprecated old synonym for field#'field_name'=>'svcnum',
+             'find_button' => 1, #add a "find" button to the field
+             'curr_value'  => 54, #current value
+             'value        => 32, #deprecated synonym for curr_value
+  );
+
+</%doc>
+<INPUT TYPE="hidden" NAME="<% $field %>" ID="<% $field %>" VALUE="<% $value %>">
+
+<!-- some false laziness w/ misc/batch-cust_pay.html, though not as bad as i'd thought at first... -->
+
+<INPUT TYPE = "text"
+       NAME = "<% $field %>_search"
+       ID   = "<% $field %>_search"
+       SIZE = "32"
+       VALUE="<% $svc_broadband ? $svc_broadband->label : '(svcnum, ip or mac)' %>"
+       onFocus="clearhint_<% $field %>_search(this);"
+       onClick="clearhint_<% $field %>_search(this);"
+       onChange="smart_<% $field %>_search(this);"
+>
+
+% if ( $opt{'find_button'} ) {
+    <INPUT TYPE    = "button"
+           VALUE   = 'Find',
+           NAME    = "<% $field %>_findbutton"
+           onClick = "smart_<% $field %>_search(this.form.<% $field %>_search);"
+    >
+% }
+
+<SELECT NAME="<% $field %>_select" ID="<% $field %>_select" STYLE="color:#ff0000; display:none" onChange="select_<% $field %>(this);">
+</SELECT>
+
+<% include('/elements/xmlhttp.html',
+              'url'  => $p. 'misc/xmlhttp-svc_broadband-search.cgi',
+              'subs' => [ 'smart_search' ],
+           )
+%>
+
+<SCRIPT TYPE="text/javascript">
+
+  function clearhint_<% $field %>_search (what) {
+
+    what.style.color = '#000000';
+
+    if ( what.value == '(svcnum, ip or mac)' )
+      what.value = '';
+
+    if ( what.value.indexOf('Service not found: ') == 0 )
+      what.value = what.value.substr(20);
+
+  }
+
+  var <% $field %>_search_active = false;
+
+  function smart_<% $field %>_search(what) {
+
+    if ( <% $field %>_search_active )
+      return;
+
+    var service = what.value;
+
+    if ( service == 'searching...' || service == ''
+         || service.indexOf('Service not found: ') == 0 )
+      return;
+
+    if ( what.getAttribute('magic') == 'nosearch' ) {
+      what.setAttribute('magic', '');
+      return;
+    }
+
+    //what.value = 'searching...'
+    what.disabled = true;
+    what.style.color= '#000000';
+    what.style.backgroundColor = '#dddddd';
+
+    var service_select = document.getElementById('<% $field %>_select');
+
+    //alert("search for customer " + customer);
+
+    function <% $field %>_search_update(services) {
+
+      //alert('customers returned: ' + customers);
+
+      var serviceArray = eval('(' + services + ')');
+
+      what.disabled = false;
+      what.style.backgroundColor = '#ffffff';
+
+      if ( serviceArray.length == 0 ) {
+
+        what.form.<% $field %>.value = '';
+
+        what.value = 'Service not found: ' + what.value;
+        what.style.color = '#ff0000';
+
+        what.style.display = '';
+        service_select.style.display = 'none';
+
+      } else if ( serviceArray.length == 1 ) {
+
+        //alert('one customer found: ' + customerArray[0]);
+
+        what.form.<% $field %>.value = serviceArray[0][0];
+        what.value = serviceArray[0][1];
+
+        what.style.display = '';
+        service_select.style.display = 'none';
+
+      } else {
+
+        //alert('multiple customers found, have to create select dropdown');
+
+        //blank the current list
+        for ( var i = service_select.length; i >= 0; i-- )
+          service_select.options[i] = null;
+
+        opt(service_select, '', 'Multiple services match "' + service + '" - select one', '#ff0000');
+
+        //add the multiple services
+        for ( var s = 0; s < serviceArray.length; s++ )
+          opt(service_select, serviceArray[s][0], serviceArray[s][1], '#000000');
+
+        opt(service_select, 'cancel', '(Edit search string)', '#000000');
+
+        what.style.display = 'none';
+        service_select.style.display = '';
+
+      }
+
+      <% $field %>_search_active = false;
+
+    }
+
+    <% $field %>_search_active = true;
+
+    smart_search( service, <% $field %>_search_update );
+
+
+  }
+
+  function select_<% $field %> (what) {
+
+    var svcnum = what.options[what.selectedIndex].value;
+    var service = what.options[what.selectedIndex].text;
+
+    var service_obj = document.getElementById('<% $field %>_search');
+
+    if ( svcnum == '' ) {
+      //what.style.color = '#ff0000';
+
+    } else if ( svcnum == 'cancel' ) {
+
+      service_obj.style.color = '#000000';
+
+      what.style.display = 'none';
+      service_obj.style.display = '';
+      service_obj.focus();
+
+    } else {
+    
+      what.form.<% $field %>.value = svcnum;
+
+      service_obj.value = service;
+      service_obj.style.color = '#000000';
+
+      what.style.display = 'none';
+      service_obj.style.display = '';
+
+    }
+
+  }
+
+  function opt(what,value,text,color) {
+    var optionName = new Option(text, value, false, false);
+    optionName.style.color = color;
+    var length = what.length;
+    what.options[length] = optionName;
+  }
+
+</SCRIPT>
+<%init>
+
+my( %opt ) = @_;
+
+my $field = $opt{'field'} || $opt{'field_name'} || 'svcnum';
+
+my $value = $opt{'curr_value'} || $opt{'value'};
+
+my $svc_broadband = '';
+if ( $value ) {
+  $svc_broadband = qsearchs({
+    'table'     => 'svc_broadband',
+    'hashref'   => { 'svcnum' => $value },
+    #have to join to cust_main for an agentnum 'extra_sql' => " AND ". $FS::CurrentUser::CurrentUser->agentnums_sql,
+  });
+}
+
+</%init>
diff --git a/httemplate/elements/tr-search-svc_broadband.html b/httemplate/elements/tr-search-svc_broadband.html
new file mode 100644 (file)
index 0000000..cd7c115
--- /dev/null
@@ -0,0 +1,15 @@
+<& tr-td-label.html, @_  &>
+
+  <TD <% $colspan %> <% $cell_style %> ID="<% $opt{input_id} || $opt{id}.'_input0' %>"><& search-svc_broadband.html, @_  &></TD>
+
+</TR>
+
+<%init>
+
+my %opt = @_;
+
+my $cell_style = $opt{'cell_style'} ? 'STYLE="'. $opt{'cell_style'}. '"' : '';
+
+my $colspan = $opt{'colspan'} ? 'COLSPAN="'.$opt{'colspan'}.'"' : '';
+
+</%init>
diff --git a/httemplate/misc/xmlhttp-svc_broadband-search.cgi b/httemplate/misc/xmlhttp-svc_broadband-search.cgi
new file mode 100644 (file)
index 0000000..578e614
--- /dev/null
@@ -0,0 +1,22 @@
+% if ( $sub eq 'smart_search' ) {
+%
+%   my $string = $cgi->param('arg');
+%   my @svc_broadband = FS::svc_broadband->smart_search( $string );
+%   my $return = [ map { my $cust_pkg = $_->cust_svc->cust_pkg;
+%                        [ $_->svcnum,
+%                          $_->label. ( $cust_pkg
+%                                        ? ' ('. $cust_pkg->cust_main->name. ')'
+%                                        : ''
+%                                     ),
+%                        ];
+%                      } 
+%                    @svc_broadband,
+%                ];
+%     
+<% encode_json($return) %>\
+% }
+<%init>
+
+my $sub = $cgi->param('sub');
+
+</%init>
index 05b6ac5..7d6520e 100644 (file)
@@ -36,6 +36,14 @@ my @fields = (
   #'longitude',
   { field => 'coordinates', value_callback => \&coordinates },
   'altitude',
+
+  'radio_serialnum',
+  'radio_location',
+  'poe_location',
+  'rssi',
+  'suid',
+  { field => 'shared_svcnum', value_callback=> \&shared_svcnum, }, #value_callback => 
+
   'vlan_profile',
   'authkey',
   'plan_id',
@@ -112,9 +120,36 @@ sub coordinates {
     );
 }
 
+sub shared_svcnum {
+  my $svc_broadband = shift;
+  return '' unless $svc_broadband->shared_svcnum;
+
+  my $shared_svc_broadband =
+    qsearchs('svc_broadband', { 'svcnum' => $svc_broadband->shared_svcnum,
+                              }
+                              #agent virt?
+            )
+      or return '';
+  my $shared_cust_pkg = $shared_svc_broadband->cust_svc->cust_pkg;
+
+  $shared_svc_broadband->label.
+    ( $shared_cust_pkg
+         ? ' ('. $shared_cust_pkg->cust_main->name. ')'
+         : ''
+    );
+}
+
 sub svc_callback {
   # trying to move to the callback style
   my ($cgi, $svc_x, $part_svc, $cust_pkg, $fields, $opt) = @_;
+
+  if (    $part_svc->part_svc_column('latitude')->columnflag eq 'F' 
+       && $part_svc->part_svc_column('longitude')->columnflag eq 'F' 
+     )
+  {
+    @$fields = grep { !ref($_) || $_->{field} ne 'coordinates' } @$fields;
+  }
+
   # again, we assume at most one of these exports per part_svc
   my ($nas_export) = $part_svc->part_export('broadband_nas');
   if ( $nas_export ) {