X-Git-Url: http://git.freeside.biz/gitweb/?p=freeside.git;a=blobdiff_plain;f=FS%2FFS%2Fsvc_broadband.pm;h=5ffe0e452cd75a616e4cd1b6b577d66c1a56daeb;hp=eb29646353177ffbf2cfe38b01b192c45d4097b2;hb=74e058c8a010ef6feb539248a550d0bb169c1e94;hpb=64916ad920572e19351df79127d4822fab57f621 diff --git a/FS/FS/svc_broadband.pm b/FS/FS/svc_broadband.pm index eb2964635..5ffe0e452 100755 --- a/FS/FS/svc_broadband.pm +++ b/FS/FS/svc_broadband.pm @@ -6,6 +6,7 @@ use FS::Record qw( qsearchs qsearch dbh ); use FS::svc_Common; use FS::cust_svc; use FS::addr_block; +use FS::part_svc_router; use NetAddr::IP; @ISA = qw( FS::svc_Common ); @@ -110,6 +111,128 @@ sub table_info { sub table { 'svc_broadband'; } +sub table_dupcheck_fields { ( 'mac_addr' ); } + +=item search HASHREF + +Class method which returns a qsearch hash expression to search for parameters +specified in HASHREF. + +Parameters: + +=over 4 + +=item unlinked - set to search for all unlinked services. Overrides all other options. + +=item agentnum + +=item custnum + +=item svcpart + +=item ip_addr + +=item pkgpart - arrayref + +=item routernum - arrayref + +=item order_by + +=back + +=cut + +sub search { + my ($class, $params) = @_; + my @where = (); + my @from = ( + 'LEFT JOIN cust_svc USING ( svcnum )', + 'LEFT JOIN part_svc USING ( svcpart )', + 'LEFT JOIN cust_pkg USING ( pkgnum )', + 'LEFT JOIN cust_main USING ( custnum )', + ); + + # based on FS::svc_acct::search, probably the most mature of the bunch + #unlinked + push @where, 'pkgnum IS NULL' if $params->{'unlinked'}; + + #agentnum + if ( $params->{'agentnum'} =~ /^(\d+)$/ and $1 ) { + push @where, "agentnum = $1"; + } + push @where, $FS::CurrentUser::CurrentUser->agentnums_sql( + 'null_right' => 'View/link unlinked services', + 'table' => 'cust_main' + ); + + #custnum + if ( $params->{'custnum'} =~ /^(\d+)$/ and $1 ) { + push @where, "custnum = $1"; + } + + #pkgpart, now properly untainted, can be arrayref + for my $pkgpart ( $params->{'pkgpart'} ) { + if ( ref $pkgpart ) { + my $where = join(',', map { /^(\d+)$/ ? $1 : () } @$pkgpart ); + push @where, "cust_pkg.pkgpart IN ($where)" if $where; + } + elsif ( $pkgpart =~ /^(\d+)$/ ) { + push @where, "cust_pkg.pkgpart = $1"; + } + } + + #routernum, can be arrayref + for my $routernum ( $params->{'routernum'} ) { + push @from, 'LEFT JOIN addr_block USING ( blocknum )'; + if ( ref $routernum and grep { $_ } @$routernum ) { + my $where = join(',', map { /^(\d+)$/ ? $1 : () } @$routernum ); + push @where, "addr_block.routernum IN ($where)" if $where; + } + elsif ( $routernum =~ /^(\d+)$/ ) { + push @where, "addr_block.routernum = $1"; + } + } + + #svcnum + if ( $params->{'svcnum'} =~ /^(\d+)$/ ) { + push @where, "svcnum = $1"; + } + + #svcpart + if ( $params->{'svcpart'} =~ /^(\d+)$/ ) { + push @where, "svcpart = $1"; + } + + #ip_addr + if ( $params->{'ip_addr'} =~ /^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/ ) { + push @where, "ip_addr = '$1'"; + } + + #custnum + if ( $params->{'custnum'} =~ /^(\d+)$/ and $1) { + push @where, "custnum = $1"; + } + + my $addl_from = join(' ', @from); + my $extra_sql = ''; + $extra_sql = 'WHERE '.join(' AND ', @where) if @where; + my $count_query = "SELECT COUNT(*) FROM svc_broadband $addl_from $extra_sql"; + return( { + 'table' => 'svc_broadband', + 'hashref' => {}, + 'select' => join(', ', + 'svc_broadband.*', + 'part_svc.svc', + 'cust_main.custnum', + FS::UI::Web::cust_sql_fields($params->{'cust_fields'}), + ), + 'extra_sql' => $extra_sql, + 'addl_from' => $addl_from, + 'order_by' => "ORDER BY ".($params->{'order_by'} || 'svcnum'), + 'count_query' => $count_query, + } ); +} + =item search_sql STRING Class method which returns an SQL fragment to search for the given string. @@ -217,10 +340,6 @@ sub check { ; return $error if $error; - #redundant, but prevents further problems until column constraint in place - return "MAC already in use" - if scalar( qsearch( 'svc_broadband', { 'mac_addr', $self->mac_addr } ) ); - if($self->speed_up < 0) { return 'speed_up must be positive'; } if($self->speed_down < 0) { return 'speed_down must be positive'; } @@ -247,7 +366,19 @@ sub check { } } + $error = $self->_check_ip_addr; + return $error if $error; + + $self->SUPER::check; +} + +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'); #&& !$self->blocknum + return "Must supply either address or block" unless $self->blocknum; my $next_addr = $self->addr_block->next_free_addr; @@ -256,6 +387,7 @@ sub check { } else { return "No free addresses in addr_block (blocknum: ".$self->blocknum.")"; } + } if (not($self->blocknum)) { @@ -289,9 +421,21 @@ sub check { return 'Router '.$router->routernum.' cannot provide svcpart '.$self->svcpart; } - $self->SUPER::check; + ''; } +sub _check_duplicate { + my $self = shift; + + return "MAC already in use" + if ( $self->mac_addr && + scalar( qsearch( 'svc_broadband', { 'mac_addr', $self->mac_addr } ) ) + ); + + ''; +} + + =item NetAddr Returns a NetAddr::IP object containing the IP address of this service. The netmask