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