Merge branch 'patch-3' of https://github.com/gjones2/Freeside (fix closing tag)
[freeside.git] / FS / FS / svc_IP_Mixin.pm
1 package FS::svc_IP_Mixin;
2
3 use strict;
4 use base 'FS::IP_Mixin';
5 use FS::Record qw(qsearchs qsearch);
6
7 =item addr_block
8
9 Returns the address block assigned to this service.
10
11 =item router
12
13 Returns the router assigned to this service, if there is one.
14
15 =cut
16
17 #addr_block and router methods provided by FS::IP_Mixin
18
19 =item NetAddr
20
21 Returns the address as a L<NetAddr::IP> object.  Use C<$svc->NetAddr->addr>
22 to put it into canonical string form.
23
24 =cut
25
26 sub NetAddr {
27   my $self = shift;
28   NetAddr::IP->new($self->ip_addr);
29 }
30
31 =item ip_addr
32
33 Wrapper for set/get on the IP address field.
34
35 =cut
36
37 sub ip_addr {
38   my $self = shift;
39   my $ip_field = $self->table_info->{'ip_field'}
40     or return '';
41   if ( @_ ) {
42     $self->set($ip_field, @_);
43   } else {
44     $self->get($ip_field);
45   }
46 }
47
48 =item allowed_routers
49
50 Returns a list of L<FS::router> objects allowed on this service.
51
52 =cut
53
54 sub allowed_routers {
55   my $self = shift;
56   my $svcpart = $self->svcnum ? $self->cust_svc->svcpart : $self->svcpart;
57   my @r = map { $_->router } 
58     qsearch('part_svc_router', { svcpart => $svcpart });
59
60   if ( $self->cust_main ) {
61     my $agentnum = $self->cust_main->agentnum;
62     return grep { !$_->agentnum or $_->agentnum == $agentnum } @r;
63   } else {
64     return @r;
65   }
66 }
67
68 =item svc_ip_check
69
70 Wrapper for C<ip_check> which also checks the validity of the router.
71
72 =cut
73
74 sub svc_ip_check {
75   my $self = shift;
76   my $error = $self->ip_check;
77   return $error if $error;
78   if ( my $router = $self->router ) {
79     if ( grep { $_->routernum eq $router->routernum } $self->allowed_routers ) {
80       return '';
81     } else {
82       return 'Router '.$router->routername.' not available for this service';
83     }
84   }
85   '';
86 }
87
88 sub _used_addresses {
89   my ($class, $block, $exclude) = @_;
90   my $ip_field = $class->table_info->{'ip_field'}
91     or return ();
92   # if the service doesn't have an ip_field, then it has no IP addresses 
93   # in use, yes? 
94
95   my %hash = ( $ip_field => { op => '!=', value => '' } );
96   #$hash{'blocknum'} = $block->blocknum if $block;
97   $hash{'svcnum'} = { op => '!=', value => $exclude->svcnum } if ref $exclude;
98   map { $_->NetAddr->addr } qsearch($class->table, \%hash);
99 }
100
101 sub _is_used {
102   my ($class, $addr, $exclude) = @_;
103   my $ip_field = $class->table_info->{'ip_field'}
104     or return '';
105
106   my $svc = qsearchs($class->table, { $ip_field => $addr })
107     or return '';
108
109   return '' if ( ref $exclude and $exclude->svcnum == $svc->svcnum );
110
111   my $cust_svc = $svc->cust_svc;
112   if ( $cust_svc ) {
113     my @label = $cust_svc->label;
114     # "svc_foo 1234 (Service Desc)"
115     # this should be enough to identify it without leaking customer
116     # names across agents
117     "$label[2] $label[3] ($label[0])";
118   } else {
119     join(' ', $class->table, $svc->svcnum, '(unlinked service)');
120   }
121 }
122
123 1;