X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2Fsvc_broadband.pm;h=df5a438d6ed5cbfbc979eb0d44b6c11abb805ffa;hb=311711639b41a5b307243d99c1aefceadcc97548;hp=43a0dcd53b8a512be901dd14bf16ea0b26f7f0f0;hpb=4347107a70dd00e9ce0b57e4aaede742edc5fe9c;p=freeside.git diff --git a/FS/FS/svc_broadband.pm b/FS/FS/svc_broadband.pm index 43a0dcd53..df5a438d6 100755 --- a/FS/FS/svc_broadband.pm +++ b/FS/FS/svc_broadband.pm @@ -1,9 +1,14 @@ package FS::svc_broadband; +use base qw( + FS::svc_Radius_Mixin + FS::svc_Tower_Mixin + FS::svc_MAC_Mixin + FS::svc_Common + ); use strict; use vars qw(@ISA $conf); -use base qw(FS::svc_Radius_Mixin FS::svc_Tower_Mixin FS::svc_Common); { no warnings 'redefine'; use NetAddr::IP; } use FS::Record qw( qsearchs qsearch dbh ); use FS::svc_Common; @@ -91,9 +96,9 @@ points to. You can ask the object for a copy with the I method. sub table_info { { - 'name' => 'Broadband', - 'name_plural' => 'Broadband services', - 'longname_plural' => 'Fixed (username-less) broadband services', + 'name' => 'Wireless broadband', + 'name_plural' => 'Wireless broadband services', + 'longname_plural' => 'Fixed wireless broadband services', 'display_weight' => 50, 'cancel_weight' => 70, 'ip_field' => 'ip_addr', @@ -246,6 +251,12 @@ sub search { push @where, "svcpart = $1"; } + #exportnum + if ( $params->{'exportnum'} =~ /^(\d+)$/ ) { + push @from, 'LEFT JOIN export_svc USING ( svcpart )'; + push @where, "exportnum = $1"; + } + #ip_addr if ( $params->{'ip_addr'} =~ /^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/ ) { push @where, "ip_addr = '$1'"; @@ -271,7 +282,7 @@ sub search { ), 'extra_sql' => $extra_sql, 'addl_from' => $addl_from, - 'order_by' => "ORDER BY ".($params->{'order_by'} || 'svcnum'), + 'order_by' => ($params->{'order_by'} || 'ORDER BY svcnum'), 'count_query' => $count_query, } ); } @@ -286,10 +297,14 @@ 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-F0-9]{12})$/i ) { $class->search_sql_field('mac_addr', uc($string)); - }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 =~ /^(([A-F0-9]{2}:){5}([A-F0-9]{2}))$/i ) { + $string =~ s/://g; + $class->search_sql_field('mac_addr', uc($string) ); + } elsif ( $string =~ /^(\d+)$/ ) { + my $table = $class->table; + "$table.svcnum = $1"; } else { '1 = 0'; #false } @@ -297,13 +312,18 @@ sub search_sql { =item label -Returns the IP address. +Returns the IP address, MAC address and description. =cut sub label { my $self = shift; - $self->ip_addr; + my $label = 'IP:'. ($self->ip_addr || 'Unknown'); + $label .= ', MAC:'. $self->mac_addr + if $self->mac_addr; + $label .= ' ('. $self->description. ')' + if $self->description; + return $label; } =item insert [ , OPTION => VALUE ... ] @@ -365,7 +385,7 @@ sub check { # remove delimiters my $mac_addr = uc($self->get('mac_addr')); - $mac_addr =~ s/[-: ]//g; + $mac_addr =~ s/[\W_]//g; $self->set('mac_addr', $mac_addr); my $error = @@ -420,14 +440,15 @@ sub check { my $router = $self->router; return "Router ".$self->routernum." does not serve this customer" - if $router->agentnum and $router->agentnum != $agentnum; + if $router->agentnum and $agentnum and $router->agentnum != $agentnum; if ( $router->manual_addr ) { $self->blocknum(''); } else { my $addr_block = $self->addr_block; - unless ( $addr_block and $addr_block->manual_flag ) { + if ( $self->ip_addr eq '' + and not ( $addr_block and $addr_block->manual_flag ) ) { my $error = $self->assign_ip_addr; return $error if $error; } @@ -463,7 +484,7 @@ sub assign_ip_addr { my @blocks; my $ip_addr; - if ( $self->blocknum and $self->addr_block->routernum == $self->routernum ) { + if ( $self->addr_block and $self->addr_block->routernum == $self->routernum ) { # simple case: user chose a block, find an address in that block # (this overrides an existing IP address if it's not in the block) @blocks = ($self->addr_block); @@ -482,15 +503,13 @@ sub assign_ip_addr { return ''; } $ip_addr = $block->next_free_addr; - last if $ip_addr; - } - if ( $ip_addr ) { - $self->set(ip_addr => $ip_addr->addr); - return ''; - } - else { - return 'No IP address available on this router'; + if ( $ip_addr ) { + $self->set(ip_addr => $ip_addr->addr); + $self->set(blocknum => $block->blocknum); + return ''; + } } + return 'No IP address available on this router'; } =item assign_router @@ -526,6 +545,12 @@ sub _check_ip_addr { else { return 'Cannot parse address: '.$self->ip_addr unless $self->NetAddr; } + + if ( $self->addr_block + and not $self->addr_block->NetAddr->contains($self->NetAddr) ) { + return 'Address '.$self->ip_addr.' not in block '.$self->addr_block->cidr; + } + # if (my $dup = qsearchs('svc_broadband', { # ip_addr => $self->ip_addr, # svcnum => {op=>'!=', value => $self->svcnum} @@ -537,9 +562,9 @@ sub _check_ip_addr { sub _check_duplicate { my $self = shift; - - $self->lock_table; - + # Not a reliable check because the table isn't locked, but + # that's why we have a unique index. This is just to give a + # friendlier error message. my @dup; @dup = $self->find_duplicates('global', 'ip_addr'); if ( @dup ) { @@ -598,7 +623,7 @@ sub allowed_routers { my $self = shift; my $svcpart = $self->svcnum ? $self->cust_svc->svcpart : $self->svcpart; my @r = map { $_->router } qsearch('part_svc_router', - { svcpart => $self->cust_svc->svcpart }); + { svcpart => $svcpart }); if ( $self->cust_main ) { my $agentnum = $self->cust_main->agentnum; return grep { !$_->agentnum or $_->agentnum == $agentnum } @r; @@ -611,22 +636,6 @@ sub allowed_routers { =back -=item mac_addr_formatted CASE DELIMITER - -Format the MAC address (for use by exports). If CASE starts with "l" -(for "lowercase"), it's returned in lowercase. DELIMITER is inserted -between octets. - -=cut - -sub mac_addr_formatted { - my $self = shift; - my ($case, $delim) = @_; - my $addr = $self->mac_addr; - $addr = lc($addr) if $case =~ /^l/i; - join( $delim || '', $addr =~ /../g ); -} - #class method sub _upgrade_data { my $class = shift; @@ -639,6 +648,11 @@ sub _upgrade_data { routernum => '' })) { my $addr_block = $self->addr_block; + if ( !$addr_block ) { + # super paranoid mode + warn "WARNING: svcnum ".$self->svcnum." is assigned to addr_block ".$self->blocknum.", which does not exist; skipped.\n"; + next; + } my $ip_addr = $self->ip_addr; my $routernum = $addr_block->routernum; if ( $routernum ) { @@ -662,6 +676,38 @@ sub _upgrade_data { ": no routernum in address block ".$addr_block->cidr.", skipped\n"; } } + + # assign blocknums to services that should have them + my @all_blocks = qsearch('addr_block', { }); + SVC: foreach my $self ( + qsearch({ + 'select' => 'svc_broadband.*', + 'table' => 'svc_broadband', + 'addl_from' => 'JOIN router USING (routernum)', + 'hashref' => {}, + 'extra_sql' => 'WHERE svc_broadband.blocknum IS NULL '. + 'AND router.manual_addr IS NULL', + }) + ) { + + next SVC if $self->ip_addr eq ''; + my $NetAddr = $self->NetAddr; + # inefficient, but should only need to run once + foreach my $block (@all_blocks) { + if ($block->NetAddr->contains($NetAddr)) { + $self->set(blocknum => $block->blocknum); + my $error = $self->replace; + warn "WARNING: error assigning blocknum ".$block->blocknum. + " to service ".$self->svcnum."\n$error; skipped\n" + if $error; + next SVC; + } + } + warn "WARNING: no block found containing ".$NetAddr->addr." for service ". + $self->svcnum; + #next SVC; + } + ''; }