use strict;
use vars qw( @ISA );
-use FS::Record qw( qsearchs qsearch );
+use FS::Record qw( qsearchs qsearch dbh );
use FS::addr_block;
-@ISA = qw( FS::Record );
+@ISA = qw( FS::Record FS::m2m_Common );
=head1 NAME
=item svcnum - svcnum of the owning FS::svc_broadband, if appropriate
+=item manual_addr - set to 'Y' to allow services linked to this router
+to have any IP address, rather than one in an address block belonging
+to the router.
+
=back
=head1 METHODS
Adds this record to the database. If there is an error, returns the error,
otherwise returns false.
-=item delete
+If the pseudo-field 'blocknum' is set to an L<FS::addr_block> number, then
+that address block will be assigned to this router. Currently only one
+block can be assigned this way.
+
+=cut
-Deletes this record from the database. If there is an error, returns the
-error, otherwise returns false.
+sub insert {
+ my $oldAutoCommit = $FS::UID::AutoCommit;
+ local $FS::UID::AutoCommit = 0;
+ my $dbh = dbh;
+
+ my $self = shift;
+ my $error = $self->SUPER::insert(@_);
+ return $error if $error;
+ if ( $self->blocknum ) {
+ my $block = FS::addr_block->by_key($self->blocknum);
+ if ($block) {
+ if ($block->routernum) {
+ $error = "block ".$block->cidr." is already assigned to a router";
+ } else {
+ $block->set('routernum', $self->routernum);
+ $block->set('manual_flag', 'Y');
+ $error = $block->replace;
+ }
+ } else {
+ $error = "blocknum ".$self->blocknum." not found";
+ }
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return $error;
+ }
+ }
+ $dbh->commit if $oldAutoCommit;
+ return $error;
+}
=item replace OLD_RECORD
Replaces OLD_RECORD with this one in the database. If there is an error,
returns the error, otherwise returns false.
+=cut
+
+sub replace {
+ my $oldAutoCommit = $FS::UID::AutoCommit;
+ local $FS::UID::AutoCommit = 0;
+ my $dbh = dbh;
+
+ my $self = shift;
+ my $old = shift || $self->replace_old;
+ my $error = $self->SUPER::replace($old, @_);
+ return $error if $error;
+
+ if ( length($self->blocknum) ) {
+ #warn "FS::router::replace: blocknum = ".$self->blocknum."\n";
+ # then release any blocks we're already holding
+ foreach my $block ($self->addr_block) {
+ $block->set('routernum', 0);
+ $block->set('manual_flag', '');
+ $error ||= $block->replace;
+ }
+ if ( !$error and $self->blocknum > 0 ) {
+ # and, if the new blocknum is a real blocknum, assign it
+ my $block = FS::addr_block->by_key($self->blocknum);
+ if ( $block ) {
+ $block->set('routernum', $self->routernum);
+ $block->set('manual_flag', '');
+ $error ||= $block->replace;
+ } else {
+ $error = "blocknum ".$self->blocknum." not found";
+ }
+ }
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return $error;
+ }
+ }
+ $dbh->commit if $oldAutoCommit;
+ return $error;
+}
+
=item check
Checks all fields to make sure this is a valid record. If there is an error,
my $error =
$self->ut_numbern('routernum')
- || $self->ut_text('routername');
+ || $self->ut_text('routername')
+ || $self->ut_enum('manual_addr', [ '', 'Y' ])
+ || $self->ut_agentnum_acl('agentnum', 'Broadband global configuration')
+ || $self->ut_foreign_keyn('svcnum', 'cust_svc', 'svcnum')
+ ;
return $error if $error;
$self->SUPER::check;
}
+=item delete
+
+Deallocate all address blocks from this router and delete it.
+
+=cut
+
+sub delete {
+ my $self = shift;
+
+ my $oldAutoCommit = $FS::UID::AutoCommit;
+ local $FS::UID::AutoCommit = 0;
+ my $dbh = dbh;
+
+ my $error;
+ foreach my $block ($self->addr_block) {
+ $block->set('manual_flag', '');
+ $block->set('routernum', 0);
+ $error ||= $block->replace;
+ }
+
+ $error ||= $self->SUPER::delete;
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return $error;
+ }
+
+ $dbh->commit or die $dbh->errstr if $oldAutoCommit;
+ '';
+}
+
=item addr_block
Returns a list of FS::addr_block objects (address blocks) associated
sub addr_block {
my $self = shift;
- return qsearch('addr_block', { routernum => $self->routernum });
+ qsearch('addr_block', { routernum => $self->routernum });
+}
+
+=item auto_addr_block
+
+Returns a list of address blocks on which auto-assignment of IP addresses
+is enabled.
+
+=cut
+
+sub auto_addr_block {
+ my $self = shift;
+ return () if $self->manual_addr;
+ return qsearch('addr_block', { routernum => $self->routernum,
+ manual_flag => '' });
}
=item part_svc_router
$self->part_svc_router;
}
-=back
+=item agent
-=head1 VERSION
+Returns the agent associated with this router, if any.
-$Id:
+=cut
+
+sub agent {
+ qsearchs('agent', { 'agentnum' => shift->agentnum });
+}
+
+=item cust_svc
+
+Returns the cust_svc associated with this router, if any. This should be
+the service that I<provides connectivity to the router>, not any service
+connected I<through> the router.
-=head1 BUGS
+=cut
+
+sub cust_svc {
+ my $svcnum = shift->svcnum or return undef;
+ FS::cust_svc->by_key($svcnum);
+}
+
+=back
=head1 SEE ALSO