add svc_fiber circuit id field, OLT sites, and other improvements, #35260
[freeside.git] / FS / FS / svc_fiber.pm
1 package FS::svc_fiber;
2
3 use strict;
4 use base qw( FS::svc_Common );
5 use FS::cust_svc;
6 use FS::hardware_type;
7 use FS::fiber_olt;
8 use FS::Record 'dbh';
9
10 =head1 NAME
11
12 FS::svc_fiber - Object methods for svc_fiber records
13
14 =head1 SYNOPSIS
15
16   use FS::table_name;
17
18   $record = new FS::table_name \%hash;
19   $record = new FS::table_name { 'column' => 'value' };
20
21   $error = $record->insert;
22
23   $error = $new_record->replace($old_record);
24
25   $error = $record->delete;
26
27   $error = $record->check;
28
29   $error = $record->suspend;
30
31   $error = $record->unsuspend;
32
33   $error = $record->cancel;
34
35 =head1 DESCRIPTION
36
37 An FS::svc_fiber object represents a fiber-to-the-premises service.  
38 FS::svc_fiber inherits from FS::svc_Common.  The following fields are
39 currently supported:
40
41 =over 4
42
43 =item svcnum - Primary key
44
45 =item oltnum - The Optical Line Terminal this service connects to (see
46 L<FS::fiber_olt>).
47
48 =item shelf - The shelf number on the OLT.
49
50 =item card - The card number on the OLT shelf.
51
52 =item olt_port - The port number on that card.
53
54 =item vlan - The VLAN number.
55
56 =item signal - Measured signal strength in dB.
57
58 =item speed_up - Measured uplink speed in Mbps.
59
60 =item speed_down - Measured downlink speed in Mbps.
61
62 =back
63
64 =head1 METHODS
65
66 =over 4
67
68 =item new HASHREF
69
70 Creates a new fiber service record.  To add it to the database, see L<"insert">.
71
72 =cut
73
74 sub table { 'svc_fiber'; }
75
76 sub table_info {
77   {
78     'name' => 'Fiber',
79     'name_plural' => 'Fiber', # really the name of the ACL
80     'longname_plural' => 'Fiber services',
81     'sorts' => [ 'oltnum', ],
82     'display_weight' => 74,
83     'cancel_weight'  => 74,
84     'fields' => {
85       'oltnum'        => {
86                           'label'        => 'OLT',
87                           'type'         => 'select',
88                           'select_table' => 'fiber_olt',
89                           'select_key'   => 'oltnum',
90                           'select_label' => 'oltname',
91                           'disable_inventory' => 1,
92                          },
93       'shelf'         => {
94                           'label' => 'Shelf',
95                           'type'  => 'text',
96                           'disable_inventory' => 1,
97                           'disable_select'    => 1,
98                          },
99       'card'          => {
100                           'label' => 'Card',
101                           'type'  => 'text',
102                           'disable_inventory' => 1,
103                           'disable_select'    => 1,
104                          },
105       'olt_port'      => {
106                           'label' => 'GPON port',
107                           'type'  => 'text',
108                           'disable_inventory' => 1,
109                           'disable_select'    => 1,
110                          },
111       # ODN circuit
112       'circuit_id'    => {
113                           'label' => 'ODN circuit',
114                           'type'  => 'input-fiber_circuit',
115                           'disable_inventory' => 1,
116                           'disable_select'    => 1,
117                          },
118       # ONT stuff
119       'ont_id'        => {
120                           'label' => 'ONT #',
121                           'disable_select'    => 1,
122                          },
123       'ont_typenum'   => {
124                           'label' => 'Device type',
125                           'type'  => 'select-hardware',
126                           'disable_select'    => 1,
127                           'disable_default'   => 1,
128                           'disable_inventory' => 1,
129                          },
130       'ont_serial'    => {
131                           'label' => 'Serial number',
132                           'disable_select'    => 1,
133                          },
134       'ont_port'      => {
135                           'label' => 'GE port',
136                           'type'  => 'text',
137                           'disable_inventory' => 1,
138                           'disable_select'    => 1,
139                          },
140       'vlan'          => {
141                           'label' => 'VLAN #',
142                           'type'  => 'text',
143                           'disable_inventory' => 1,
144                           'disable_select'    => 1,
145                          },
146       'signal'        => {
147                           'label' => 'Signal strength (dB)',
148                           'type'  => 'text',
149                           'disable_inventory' => 1,
150                           'disable_select'    => 1,
151                          },
152       'speed_down'    => {
153                           'label' => 'Download speed (Mbps)',
154                           'type'  => 'text',
155                           'disable_inventory' => 1,
156                           'disable_select'    => 1,
157                          },
158       'speed_up'      => {
159                           'label' => 'Upload speed (Mbps)',
160                           'type'  => 'text',
161                           'disable_inventory' => 1,
162                           'disable_select'    => 1,
163                          },
164       'ont_install'   => {
165                           'label' => 'ONT install location',
166                           'type'  => 'text',
167                           'disable_inventory' => 1,
168                           'disable_select'    => 1,
169                          },
170     },
171   };
172 }
173
174 =item search_sql STRING
175
176 Class method which returns an SQL fragment to search for the given string.
177 For svc_fiber, STRING can be a full or partial ONT serial number.
178
179 =cut
180
181 #or something more complicated if necessary
182 sub search_sql {
183   my($class, $string) = @_;
184   $string = dbh->quote('%' . $string . '%');
185   "LOWER(svc_fiber.ont_serial) LIKE LOWER($string)";
186 }
187
188 =item label
189
190 Returns a description of this fiber service containing the circuit ID
191 and the ONT serial number.
192
193 =cut
194
195 sub label {
196   my $self = shift;
197   $self->ont_serial . ' @ ' . $self->circuit_id;
198 }
199
200 # nothing special for insert, delete, or replace
201
202 =item insert
203
204 Adds this record to the database.  If there is an error, returns the error,
205 otherwise returns false.
206
207 The additional fields pkgnum and svcpart (see L<FS::cust_svc>) should be 
208 defined.  An FS::cust_svc record will be created and inserted.
209
210 =item delete
211
212 Delete this record from the database.
213
214 =item replace OLD_RECORD
215
216 Replaces the OLD_RECORD with this one in the database.  If there is an error,
217 returns the error, otherwise returns false.
218
219 =item suspend
220
221 Called by the suspend method of FS::cust_pkg (see L<FS::cust_pkg>).
222
223 =item unsuspend
224
225 Called by the unsuspend method of FS::cust_pkg (see L<FS::cust_pkg>).
226
227 =item cancel
228
229 Called by the cancel method of FS::cust_pkg (see L<FS::cust_pkg>).
230
231 =item check
232
233 Checks all fields to make sure this is a valid example.  If there is
234 an error, returns the error, otherwise returns false.  Called by the insert
235 and repalce methods.
236
237 =cut
238
239 sub check {
240   my $self = shift;
241
242   my $x = $self->setfixed;
243   return $x unless ref($x);
244   my $part_svc = $x;
245
246   my $error =
247        $self->ut_number('oltnum')
248     || $self->ut_numbern('shelf')
249     || $self->ut_numbern('card')
250     || $self->ut_numbern('olt_port')
251     || $self->ut_number('ont_id')
252     || $self->ut_number('ont_typenum')
253     || $self->ut_alphan('ont_serial')
254     || $self->ut_alphan('ont_port')
255     || $self->ut_numbern('vlan')
256     || $self->ut_sfloatn('signal')
257     || $self->ut_numbern('speed_up')
258     || $self->ut_numbern('speed_down')
259     || $self->ut_textn('ont_install')
260   ;
261   return $error if $error;
262
263   $self->set('signal', sprintf('%.2f', $self->get('signal')));
264
265   $self->SUPER::check;
266 }
267
268 =item ont_description
269
270 Returns the description of the ONT hardware, if there is one.
271
272 =cut
273
274 sub ont_description {
275   my $self = shift;
276   $self->ont_typenum ? $self->hardware_type->description : '';
277 }
278
279 =item search HASHREF
280
281 Returns a qsearch hash expression to search for parameters specified in
282 HASHREF.
283
284 Parameters are those in L<FS::svc_Common/search>, plus:
285
286 ont_typenum - the ONT L<FS::hardware_type> key
287
288 oltnum - the OLT L<FS::fiber_olt> key
289
290 shelf, card, olt_port - the OLT port location fields
291
292 vlan - the VLAN number
293
294 ont_serial - the ONT serial number
295
296 =cut
297
298 sub _search_svc {
299   my ($class, $params, $from, $where) = @_;
300
301   # make this simple: all of these are numeric fields, except that 0 means null
302   foreach my $field (qw(ont_typenum oltnum shelf olt_port card vlan)) {
303     if ( $params->{$field} =~ /^(\d+)$/ ) {
304       push @$where, "COALESCE($field,0) = $1";
305     }
306   }
307   if ( length($params->{ont_serial}) ) {
308     my $string = dbh->quote('%'.$params->{ont_serial}.'%');
309     push @$where, "LOWER(ont_serial) LIKE LOWER($string)";
310   }
311
312 }
313
314 #stub still needed under 4.x+
315
316 sub hardware_type {
317   my $self = shift;
318   $self->ont_typenum ? FS::hardware_type->by_key($self->ont_typenum) : '';
319 }
320
321 =back
322
323 =head1 SEE ALSO
324
325 L<FS::svc_Common>, L<FS::Record>, L<FS::cust_svc>, L<FS::part_svc>,
326 L<FS::cust_pkg>, schema.html from the base documentation.
327
328 =cut
329
330 1;
331