X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2Fsvc_broadband.pm;h=af8135304250921160527025ce1ac5e2fdab61de;hb=87f255507af9f14dfbccd37eefd71a148f9af344;hp=6f5e170a345e3099d299e9b7fa04500fd0537b5b;hpb=0995724c15003c7c8a734c895c3044fa1af46506;p=freeside.git diff --git a/FS/FS/svc_broadband.pm b/FS/FS/svc_broadband.pm index 6f5e170a3..af8135304 100755 --- a/FS/FS/svc_broadband.pm +++ b/FS/FS/svc_broadband.pm @@ -1,5 +1,10 @@ package FS::svc_broadband; -use base qw(FS::svc_Radius_Mixin FS::svc_Tower_Mixin FS::svc_Common); +use base qw( + FS::svc_Radius_Mixin + FS::svc_Tower_Mixin + FS::svc_IP_Mixin + FS::svc_Common + ); use strict; use vars qw($conf); @@ -135,7 +140,7 @@ sub table_info { sub table { 'svc_broadband'; } -sub table_dupcheck_fields { ( 'mac_addr' ); } +sub table_dupcheck_fields { ( 'ip_addr', 'mac_addr' ); } =item search HASHREF @@ -245,6 +250,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'"; @@ -406,28 +417,13 @@ sub check { } my $agentnum = $cust_pkg->cust_main->agentnum if $cust_pkg; - if ($self->routernum) { - return "Router ".$self->routernum." does not provide this service" - unless qsearchs('part_svc_router', { - svcpart => $svcpart, - routernum => $self->routernum - }); - - my $router = $self->router; - return "Router ".$self->routernum." does not serve this customer" - if $router->agentnum and $router->agentnum != $agentnum; - - if ( $router->auto_addr ) { - my $addr_block = $self->addr_block; - unless ( $addr_block and $addr_block->manual_flag ) { - my $error = $self->assign_ip_addr; - return $error if $error; - } - } - else { - $self->blocknum(''); - } - } # if $self->routernum + # assign IP address / router / block + $error = $self->svc_ip_check; + return $error if $error; + if ( !$self->ip_addr + and !$conf->exists('svc_broadband-allow_null_ip_addr') ) { + return 'IP address is required'; + } if ( $cust_pkg && ! $self->latitude && ! $self->longitude ) { my $l = $cust_pkg->cust_location_or_main; @@ -440,131 +436,23 @@ sub check { } } - $error = $self->_check_ip_addr; - return $error if $error; - $self->SUPER::check; } -=item assign_ip_addr - -Assign an address block matching the selected router, and the selected block -if there is one. - -=cut - -sub assign_ip_addr { - my $self = shift; - my @blocks; - my $ip_addr; - - if ( $self->blocknum 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); - } - elsif ( $self->routernum ) { - @blocks = $self->router->auto_addr_block; - } - else { - return ''; - } - - foreach my $block ( @blocks ) { - if ( $self->ip_addr and $block->NetAddr->contains($self->NetAddr) ) { - # don't change anything - 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'; - } -} - -sub _check_ip_addr { - my $self = shift; - - if (not($self->ip_addr) or $self->ip_addr eq '0.0.0.0') { - return '' if $conf->exists('svc_broadband-allow_null_ip_addr'); - return 'IP address required'; - } -# if (my $dup = qsearchs('svc_broadband', { -# ip_addr => $self->ip_addr, -# svcnum => {op=>'!=', value => $self->svcnum} -# }) ) { -# return 'IP address conflicts with svcnum '.$dup->svcnum; -# } - ''; -} - sub _check_duplicate { my $self = shift; - - return "MAC already in use" - if ( $self->mac_addr && - scalar( qsearch( 'svc_broadband', { 'mac_addr', $self->mac_addr } ) ) - ); + # 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', 'mac_addr'); + if ( @dup ) { + return "MAC address in use (svcnum ".$dup[0]->svcnum.")"; + } ''; } - -=item NetAddr - -Returns a NetAddr::IP object containing the IP address of this service. The netmask -is /32. - -=cut - -sub NetAddr { - my $self = shift; - new NetAddr::IP ($self->ip_addr); -} - -=item addr_block - -Returns the FS::addr_block record (i.e. the address block) for this broadband service. - -=cut - -sub addr_block { - my $self = shift; - qsearchs('addr_block', { blocknum => $self->blocknum }); -} - -=item router - -Returns the FS::router record for this service. - -=cut - -sub router { - my $self = shift; - qsearchs('router', { routernum => $self->routernum }); -} - -=item allowed_routers - -Returns a list of allowed FS::router objects. - -=cut - -sub allowed_routers { - my $self = shift; - my $svcpart = $self->svcnum ? $self->cust_svc->svcpart : $self->svcpart; - map { $_->router } qsearch('part_svc_router', - { svcpart => $self->cust_svc->svcpart }); -} - -=back - - =item mac_addr_formatted CASE DELIMITER Format the MAC address (for use by exports). If CASE starts with "l" @@ -593,6 +481,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 ) { @@ -602,13 +495,13 @@ sub _upgrade_data { # (other than setting blocknum to null for a non-auto-assigned router) if ( $self->ip_addr ne $ip_addr or ($self->blocknum and $self->blocknum != $addr_block->blocknum)) { - die "Upgrading service ".$self->svcnum." would change its block/address.\n\nCheck your router and address block configuration.\n"; + warn "WARNING: Upgrading service ".$self->svcnum." would change its block/address; skipped.\n"; next; } $error ||= $self->replace; - die "error assigning routernum $routernum to service ".$self->svcnum. - ":\n$error\n" + warn "WARNING: error assigning routernum $routernum to service ".$self->svcnum. + ":\n$error; skipped\n" if $error; } else { @@ -616,6 +509,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; + } + ''; }