},
{
+ 'key' => 'auto_router',
+ 'section' => '',
+ 'description' => 'Automatically choose the correct router/block based on supplied ip address when possible while provisioning broadband services',
+ 'type' => 'checkbox',
+ },
+
+ {
'key' => 'hidecancelledpackages',
'section' => 'UI',
'description' => 'Prevent cancelled packages from showing up in listings (though they will still be in the database)',
'ip_gateway', 'varchar', '', 15, '', '',
'ip_netmask', 'int', '', '', '', '',
'agentnum', 'int', 'NULL', '', '', '',
+ 'manual_flag', 'char', 'NULL', 1, '', '',
],
'primary_key' => 'blocknum',
'unique' => [ [ 'blocknum', 'routernum' ] ],
=item ip_netmask - the netmask of the block, expressed as an integer.
+=item manual_flag - prohibit automatic ip assignment from this block when true.
+
=item agentnum - optional agent number (see L<FS::agent>)
=back
$self->ut_number('routernum')
|| $self->ut_ip('ip_gateway')
|| $self->ut_number('ip_netmask')
+ || $self->ut_enum('manual_flag', [ '', 'Y' ])
|| $self->ut_agentnum_acl('agentnum', 'Broadband global configuration')
;
return $error if $error;
Returns a NetAddr::IP object corresponding to the first unassigned address
in the block (other than the network, broadcast, or gateway address). If
-there are no free addresses, returns false.
+there are no free addresses, returns false. There are never free addresses
+when manual_flag is true.
=cut
sub next_free_addr {
my $self = shift;
+ return '' if $self->manual_flag;
+
my $conf = new FS::Conf;
my @excludeaddr = $conf->config('exclude_ip_addr');
my $error =
$self->ut_numbern('svcnum')
- || $self->ut_foreign_key('blocknum', 'addr_block', 'blocknum')
+ || $self->ut_numbern('blocknum')
|| $self->ut_textn('description')
|| $self->ut_number('speed_up')
|| $self->ut_number('speed_down')
return "Invalid pkgnum" unless $cust_pkg;
}
- if ($cust_pkg) {
+ if ($self->blocknum) {
+ $error = $self->ut_foreign_key('blocknum', 'addr_block', 'blocknum');
+ return $error if $error;
+ }
+
+ if ($cust_pkg && $self->blocknum) {
my $addr_agentnum = $self->addr_block->agentnum;
if ($addr_agentnum && $addr_agentnum != $cust_pkg->cust_main->agentnum) {
return "Address block does not service this customer";
}
if (not($self->ip_addr) or $self->ip_addr eq '0.0.0.0') {
+ return "Must supply either address or block"
+ unless $self->blocknum;
my $next_addr = $self->addr_block->next_free_addr;
if ($next_addr) {
$self->ip_addr($next_addr->addr);
}
}
+ if (not($self->blocknum)) {
+ return "Must supply either address or block"
+ unless ($self->ip_addr and $self->ip_addr ne '0.0.0.0');
+ my @block = grep { $_->NetAddr->contains($self->NetAddr) }
+ map { $_->addr_block }
+ $self->allowed_routers;
+ if (scalar(@block)) {
+ $self->blocknum($block[0]->blocknum);
+ }else{
+ return "Address not with available block.";
+ }
+ }
+
# This should catch errors in the ip_addr. If it doesn't,
# they'll almost certainly not map into the block anyway.
my $self_addr = $self->NetAddr; #netmask is /32
'Router',
'Action(s)',
'',
+ '',
],
'fields' => [ 'NetAddr',
sub { my $block = shift;
},
$allocate_text,
sub { shift->router ? '' : '<FONT SIZE="-2">(split)</FONT>' },
+ sub { '<FONT SIZE="-2">('. (shift->manual_flag ? 'allow' : 'prevent'). ' automatic ip assignment)</FONT>' },
],
'links' => [ '',
'',
[ 'javascript:void(0)', '' ],
$split_link,
+ $autoassign_link,
],
'link_onclicks' => [ '',
'',
$ref;
};
+my $autoassign_link = sub {
+ my $block = shift;
+ my $url = "$path/manual_flag.cgi?manual_flag=";
+ $url .= $block->manual_flag ? '' : 'Y';
+ [ "$url;blocknum=", 'blocknum' ];
+};
+
</%init>
--- /dev/null
+<% $cgi->redirect(popurl(4). "browse/addr_block.cgi?". $cgi->query_string ) %>
+<%init>
+
+my $curuser = $FS::CurrentUser::CurrentUser;
+
+die "access denied"
+ unless $curuser->access_right('Broadband configuration')
+ || $curuser->access_right('Broadband global configuration');
+
+my $error = '';
+$cgi->param('blocknum') =~ /^(\d+)$/ or die "invalid blocknum";
+my $blocknum = $1;
+
+my $addr_block = qsearchs({ 'table' => 'addr_block',
+ 'hashref' => { blocknum => $blocknum },
+ 'extra_sql' => ' AND '. $curuser->agentnums_sql(
+ 'null_right' => 'Broadband global configuration'
+ ),
+ })
+ or $error = "Unknown blocknum: $blocknum";
+
+$addr_block->manual_flag($cgi->param('manual_flag'))
+ unless $error;
+
+$error ||= $addr_block->replace;
+
+$cgi->param('error', $error)
+ if $error;
+
+</%init>
'speed_down' => 'Download speed',
'speed_up' => 'Upload speed',
'blocknum' => 'Router/Block',
- 'block_disp' => 'Router/Block',
+ 'block_label' => 'Router/Block',
'mac_addr' => 'MAC address',
'latitude' => 'Latitude',
'longitude' => 'Longitude',
# If it's stupid but it works, it's still stupid.
# -Kristian
+my $conf = new FS::Conf;
+
my @fields = (
qw( description ip_addr speed_down speed_up blocknum ),
{ field=>'block_label', type=>'fixed' },
qw( mac_addr latitude longitude altitude vlan_profile authkey )
);
+my $fixedblock = '';
+
my $callback = sub {
my ($cgi, $object, $fieldref) = @_;
if ($columndef->columnflag eq 'F') {
$fieldref->{'type'} = 'fixed';
$fieldref->{'value'} = $columndef->columnvalue;
+ $fixedblock = $fieldref->{value}
+ if $fieldref->{field} eq 'blocknum';
}
if ($object->svcnum) {
} else {
- $fieldref->{type} = 'hidden' if $fieldref->{field} eq 'block_label';
+ if ($fieldref->{field} eq 'block_label') {
+ if ($fixedblock) {
+ $object->blocknum($fixedblock);
+ $fieldref->{value} = $object->addr_block->label;
+ }else{
+ $fieldref->{type} = 'hidden';
+ }
+ }
if ($fieldref->{field} eq 'blocknum') {
+ if ( $fixedblock or $conf->exists('auto_router') ) {
+ $fieldref->{type} = 'hidden';
+ $fieldref->{value} = $fixedblock;
+ return;
+ }
+
my $cust_pkg = qsearchs( 'cust_pkg', {pkgnum => $cgi->param('pkgnum')} );
die "No cust_pkg entry!" unless $cust_pkg;