use strict;
use vars qw(@ISA $conf);
+
+use base qw(FS::svc_Radius_Mixin FS::svc_Tower_Mixin FS::svc_Common);
+use NetAddr::IP;
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 );
+use FS::tower_sector;
$FS::UID::callback{'FS::svc_broadband'} = sub {
$conf = new FS::Conf;
interfaces thus saving address space. This has been found to work on most NAT
routers available.
+=item plan_id
+
=back
=head1 METHODS
'longname_plural' => 'Fixed (username-less) broadband services',
'display_weight' => 50,
'cancel_weight' => 70,
+ 'ip_field' => 'ip_addr',
'fields' => {
- 'description' => 'Descriptive label for this particular device.',
+ 'svcnum' => 'Service',
+ 'description' => 'Descriptive label for this particular device',
'speed_down' => 'Maximum download speed for this service in Kbps. 0 denotes unlimited.',
'speed_up' => 'Maximum upload speed for this service in Kbps. 0 denotes unlimited.',
'ip_addr' => 'IP address. Leave blank for automatic assignment.',
'select_label' => 'cidr',
'disable_inventory' => 1,
},
+ 'plan_id' => 'Service Plan Id',
+ 'performance_profile' => 'Peformance Profile',
+ 'authkey' => 'Authentication key',
+ 'mac_addr' => 'MAC address',
+ 'latitude' => 'Latitude',
+ 'longitude' => 'Longitude',
+ 'altitude' => 'Altitude',
+ 'vlan_profile' => 'VLAN profile',
+ 'usergroup' => {
+ label => 'RADIUS groups',
+ type => 'select-radius_group.html',
+ #select_table => 'radius_group',
+ #select_key => 'groupnum',
+ #select_label => 'groupname',
+ disable_inventory => 1,
+ multiple => 1,
+ },
},
};
}
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, "cust_main.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.
return $x unless ref($x);
+ # remove delimiters
+ my $mac_addr = uc($self->get('mac_addr'));
+ $mac_addr =~ s/[-: ]//g;
+ $self->set('mac_addr', $mac_addr);
+
my $error =
$self->ut_numbern('svcnum')
|| $self->ut_numbern('blocknum')
+ || $self->ut_foreign_keyn('sectornum', 'tower_sector', 'sectornum')
|| $self->ut_textn('description')
- || $self->ut_number('speed_up')
- || $self->ut_number('speed_down')
+ || $self->ut_numbern('speed_up')
+ || $self->ut_numbern('speed_down')
|| $self->ut_ipn('ip_addr')
|| $self->ut_hexn('mac_addr')
|| $self->ut_hexn('auth_key')
- || $self->ut_coordn('latitude', -90, 90)
- || $self->ut_coordn('longitude', -180, 180)
+ || $self->ut_coordn('latitude')
+ || $self->ut_coordn('longitude')
|| $self->ut_sfloatn('altitude')
|| $self->ut_textn('vlan_profile')
+ || $self->ut_textn('plan_id')
;
return $error if $error;
}
}
+ if ( $cust_pkg && ! $self->latitude && ! $self->longitude ) {
+ my $l = $cust_pkg->cust_location_or_main;
+ if ( $l->ship_latitude && $l->ship_longitude ) {
+ $self->latitude( $l->ship_latitude );
+ $self->longitude( $l->ship_longitude );
+ } elsif ( $l->latitude && $l->longitude ) {
+ $self->latitude( $l->latitude );
+ $self->longitude( $l->longitude );
+ }
+ }
+
$error = $self->_check_ip_addr;
return $error if $error;