ACL for hardware class config, RT#85057
[freeside.git] / FS / FS / svc_cable.pm
1 package FS::svc_cable;
2 use base qw( FS::MAC_Mixin
3              FS::svc_Common
4            ); #FS::device_Common
5
6 use strict;
7 use Tie::IxHash;
8
9 =head1 NAME
10
11 FS::svc_cable - Object methods for svc_cable records
12
13 =head1 SYNOPSIS
14
15   use FS::svc_cable;
16
17   $record = new FS::svc_cable \%hash;
18   $record = new FS::svc_cable { 'column' => 'value' };
19
20   $error = $record->insert;
21
22   $error = $new_record->replace($old_record);
23
24   $error = $record->delete;
25
26   $error = $record->check;
27
28 =head1 DESCRIPTION
29
30 An FS::svc_cable object represents a cable subscriber.  FS::svc_cable inherits
31 from FS::Record.  The following fields are currently supported:
32
33 =over 4
34
35 =item svcnum
36
37 primary key
38
39 =item providernum
40
41 Provider (see L<FS::cable_provider>)
42
43 =item ordernum
44
45 Provider order number
46
47 =item modelnum
48
49 Cable device model (see L<FS::cable_model>)
50
51 =item serialnum
52
53 Cable device serial number
54
55 =item mac_addr
56
57 Cable device MAC address
58
59 =back
60
61 =head1 METHODS
62
63 =over 4
64
65 =item new HASHREF
66
67 Creates a new record.  To add the record to the database, see L<"insert">.
68
69 Note that this stores the hash reference, not a distinct copy of the hash it
70 points to.  You can ask the object for a copy with the I<hash> method.
71
72 =cut
73
74 sub table { 'svc_cable'; }
75
76 sub table_dupcheck_fields { ( 'serialnum', 'mac_addr' ); }
77
78 sub search_sql {
79   my( $class, $string ) = @_;
80   if ( $string =~ /^([A-F0-9]{12})$/i ) {
81     $class->search_sql_field('mac_addr', uc($string));
82   } elsif ( $string =~ /^(([A-F0-9]{2}:){5}([A-F0-9]{2}))$/i ) {
83     $string =~ s/://g;
84     $class->search_sql_field('mac_addr', uc($string) );
85   } elsif ( $string =~ /^(\w+)$/ ) {
86     $class->search_sql_field('serialnum', $1);
87   } else {
88     '1 = 0'; #false
89   }
90 }
91
92 sub table_info {
93
94   tie my %fields, 'Tie::IxHash',
95     'svcnum'      => 'Service',
96     'providernum' => { label             => 'Provider',
97                        type              => 'select-cable_provider',
98                        disable_inventory => 1,
99                        disable_select    => 1,
100                        value_callback    => sub {
101                                               my $svc = shift;
102                                               my $p = $svc->cable_provider;
103                                               $p ? $p->provider : '';
104                                             },
105                      },
106     'ordernum'    => 'Order number', #XXX "Circuit ID/Order number"
107     'modelnum'    => { label             => 'Model',
108                        type              => 'select-cable_model',
109                        disable_inventory => 1,
110                        disable_select    => 1,
111                        value_callback    => sub {
112                                               my $svc = shift;
113                                               $svc->cable_model->model_name;
114                                             },
115                      },
116     'serialnum'   => 'Serial number',
117     'mac_addr'    => { label          => 'MAC address',
118                        type           => 'input-mac_addr',
119                        value_callback => sub {
120                                            my $svc = shift;
121                                            $svc->mac_addr_formatted('U',':');
122                                          },
123                      },
124   ;
125
126   {
127     'name'            => 'Cable Subscriber',
128     #'name_plural'     => '', #optional,
129     #'longname_plural' => '', #optional
130     'fields'          => \%fields,
131     'sorts'           => [ 'svcnum', 'serialnum', 'mac_addr', ],
132     'display_weight'  => 54,
133     'cancel_weight'   => 70, #?  no deps, so
134   };
135 }
136
137 =item label
138
139 Returns the MAC address and serial number.
140
141 =cut
142
143 sub label {
144   my $self = shift;
145   my $part_svc = $self->cust_svc->part_svc;
146   my @label = ();
147   push @label, 'MAC:'. $self->mac_addr_pretty
148     if $self->mac_addr;
149   if ( $self->serialnum ) {
150     my $serialnum_label = $part_svc->part_svc_column('serialnum');
151     push @label,
152       ($serialnum_label && $serialnum_label->columnlabel || 'Serial#').
153       $self->serialnum;
154   }
155   return join(', ', @label);
156 }
157
158 =item insert
159
160 Adds this record to the database.  If there is an error, returns the error,
161 otherwise returns false.
162
163 =item delete
164
165 Delete this record from the database.
166
167 =item replace OLD_RECORD
168
169 Replaces the OLD_RECORD with this one in the database.  If there is an error,
170 returns the error, otherwise returns false.
171
172 =item check
173
174 Checks all fields to make sure this is a valid record.  If there is
175 an error, returns the error, otherwise returns false.  Called by the insert
176 and replace methods.
177
178 =cut
179
180 sub check {
181   my $self = shift;
182
183   my $error = 
184        $self->ut_numbern('svcnum')
185     || $self->ut_foreign_keyn('providernum', 'cable_provider', 'providernum')
186     || $self->ut_alphan('ordernum')
187     || $self->ut_foreign_key('modelnum', 'cable_model', 'modelnum')
188     || $self->ut_alphan('serialnum')
189     || $self->ut_mac_addrn('mac_addr')
190   ;
191   return $error if $error;
192
193   $self->SUPER::check;
194 }
195
196 sub _check_duplicate {
197   my $self = shift;
198
199   # Not reliable checks because the table isn't locked, but that's why we have
200   # unique indices.  These are just to give friendlier error messages.
201
202   if ( $self->mac_addr ) {
203     my @dup_mac;
204     @dup_mac = $self->find_duplicates('global', 'mac_addr');
205     if ( @dup_mac ) {
206       return "MAC address in use (svcnum ".$dup_mac[0]->svcnum.")";
207     }
208   }
209
210   if ( $self->serialnum ) {
211     my @dup_serial;
212     @dup_serial = $self->find_duplicates('global', 'modelnum', 'serialnum');
213     if ( @dup_serial ) {
214       return "Serial number in use (svcnum ".$dup_serial[0]->svcnum.")";
215     }
216   }
217
218   '';
219 }
220
221 =item cable_provider
222
223 Returns the cable_provider object for this record.
224
225 =item cable_model
226
227 Returns the cable_model object for this record.
228
229 =back
230
231 =head1 BUGS
232
233 =head1 SEE ALSO
234
235 L<FS::Record>, schema.html from the base documentation.
236
237 =cut
238
239 1;
240