Merge branch 'master' of git.freeside.biz:/home/git/freeside
[freeside.git] / FS / FS / svc_circuit.pm
1 package FS::svc_circuit;
2
3 use strict;
4 use base qw(
5   FS::svc_IP_Mixin
6   FS::MAC_Mixin
7   FS::svc_Common
8 );
9 use FS::Record qw( dbh qsearch qsearchs );
10 use FS::circuit_provider;
11 use FS::circuit_type;
12 use FS::circuit_termination;
13
14 =head1 NAME
15
16 FS::svc_circuit - Object methods for svc_circuit records
17
18 =head1 SYNOPSIS
19
20   use FS::svc_circuit;
21
22   $record = new FS::svc_circuit \%hash;
23   $record = new FS::svc_circuit { 'column' => 'value' };
24
25   $error = $record->insert;
26
27   $error = $new_record->replace($old_record);
28
29   $error = $record->delete;
30
31   $error = $record->check;
32
33 =head1 DESCRIPTION
34
35 An FS::svc_circuit object represents a telecom circuit service (other than 
36 an analog phone line, which is svc_phone, or a DSL Internet connection, 
37 which is svc_dsl).  FS::svc_circuit inherits from FS::svc_IP_Mixin,
38 FS::MAC_Mixin, and FS::svc_Common.  The following fields are currently
39 supported:
40
41 =over 4
42
43 =item svcnum - primary key; see also L<FS::cust_svc>
44
45 =item typenum - circuit type (such as DS1, DS1-PRI, DS3, OC3, etc.); foreign
46 key to L<FS::circuit_type>.
47
48 =item providernum - circuit provider (telco); foreign key to 
49 L<FS::circuit_provider>.
50
51 =item termnum - circuit termination type; foreign key to 
52 L<FS::circuit_termination>
53
54 =item circuit_id - provider circuit ID string defined by the provider
55
56 =item desired_due_date - the requested date for completion of the circuit
57 order
58
59 =item due_date - the provider's committed date for completion of the circuit
60 order
61
62 =item vendor_order_id - the provider's order number
63
64 =item vendor_qual_id - the qualification number, if a qualification was 
65 performed
66
67 =item vendor_order_type -
68
69 =item vendor_order_status - the order status: ACCEPTED, PENDING, COMPLETED,
70 etc.
71
72 =item endpoint_ip_addr - the IP address of the endpoint equipment, if any. 
73 This will be validated as an IP address but not assigned from managed address
74 space or checked for uniqueness.
75
76 =item endpoint_mac_addr - the MAC address of the endpoint.
77
78 =item internal_circuit_id - internal circuit ID string
79
80 =back
81
82 =head1 METHODS
83
84 =over 4
85
86 =item new HASHREF
87
88 Creates a new circuit service.  To add the record to the database, see 
89 L<"insert">.
90
91 =cut
92
93 sub table { 'svc_circuit'; }
94
95 sub table_info {
96   my %dis = ( disable_default => 1, disable_fixed => 1,
97               disabled_inventory => 1, disable_select => 1 );
98
99   tie my %fields, 'Tie::IxHash', (
100     'svcnum'              => 'Service',
101     'providernum'         => {
102                               label         => 'Provider',
103                               type          => 'select',
104                               select_table  => 'circuit_provider',
105                               select_key    => 'providernum',
106                               select_label  => 'provider',
107                               disable_inventory => 1,
108                              },
109     'typenum'             => {
110                               label         => 'Circuit type',
111                               type          => 'select',
112                               select_table  => 'circuit_type',
113                               select_key    => 'typenum',
114                               select_label  => 'typename',
115                               disable_inventory => 1,
116                              },
117     'termnum'             => {
118                               label         => 'Termination type',
119                               type          => 'select',
120                               select_table  => 'circuit_termination',
121                               select_key    => 'termnum',
122                               select_label  => 'termination',
123                               disable_inventory => 1,
124                              },
125     'circuit_id'          => { label => 'Provider Circuit ID', %dis },
126     'desired_due_date'    => { label => 'Desired due date',
127                              %dis
128                              },
129     'due_date'            => { label => 'Due date',
130                              %dis
131                              },
132     'vendor_order_id'     => { label => 'Vendor order ID', %dis },
133     'vendor_qual_id'      => { label => 'Vendor qualification ID', %dis },
134     'vendor_order_type'   => {
135                               label => 'Vendor order type',
136                               disable_inventory => 1
137                              }, # should be a select?
138     'vendor_order_status' => {
139                               label => 'Vendor order status',
140                               disable_inventory => 1
141                              }, # should also be a select?
142     'endpoint_ip_addr'    => {
143                               label => 'Endpoint IP address',
144                              },
145     'endpoint_mac_addr'   => {
146                               label => 'Endpoint MAC address',
147                               type => 'input-mac_addr',
148                               disable_inventory => 1,
149                              },
150     'internal_circuit_id' => { label => 'Internal Circuit ID', %dis },
151   );
152   return {
153     'name'              => 'Circuit',
154     'name_plural'       => 'Circuits',
155     'longname_plural'   => 'Voice and data circuit services',
156     'display_weight'    => 72,
157     'cancel_weight'     => 85, # after svc_phone
158     'fields'            => \%fields,
159   };
160 }
161
162 =item insert
163
164 Adds this record to the database.  If there is an error, returns the error,
165 otherwise returns false.
166
167 =item delete
168
169 Delete this record from the database.
170
171 =item replace OLD_RECORD
172
173 Replaces the OLD_RECORD with this one in the database.  If there is an error,
174 returns the error, otherwise returns false.
175
176 =item check
177
178 Checks all fields to make sure this is a valid service.  If there is
179 an error, returns the error, otherwise returns false.  Called by the insert
180 and replace methods.
181
182 =cut
183
184 sub check {
185   my $self = shift;
186
187   my $mac_addr = uc($self->get('endpoint_mac_addr'));
188   $mac_addr =~ s/[\W_]//g;
189   $self->set('endpoint_mac_addr', $mac_addr);
190
191   my $error = 
192     $self->ut_numbern('svcnum')
193     || $self->ut_number('typenum')
194     || $self->ut_number('providernum')
195     || $self->ut_text('circuit_id')
196     || $self->ut_numbern('desired_due_date')
197     || $self->ut_numbern('due_date')
198     || $self->ut_textn('vendor_order_id')
199     || $self->ut_textn('vendor_qual_id')
200     || $self->ut_textn('vendor_order_type')
201     || $self->ut_textn('vendor_order_status')
202     || $self->ut_ipn('endpoint_ip_addr')
203     || $self->ut_textn('endpoint_mac_addr')
204     || $self->ut_textn('internal_circuit_id')
205   ;
206
207   # no canonical values yet for vendor_order_status or _type
208
209   return $error if $error;
210
211   $self->SUPER::check;
212 }
213
214 =item label
215
216 Returns the circuit ID.
217
218 =cut
219
220 sub label {
221   my $self = shift;
222   $self->get('circuit_id');
223 }
224
225 sub search_sql {
226   my ($class, $string) = @_;
227   my @where = ();
228   push @where, 'LOWER(svc_circuit.circuit_id) = LOWER(' . dbh->quote($string) . ')';
229   push @where, 'LOWER(circuit_provider.provider) = LOWER(' . dbh->quote($string) . ')';
230   push @where, 'LOWER(circuit_type.typename) = LOWER(' . dbh->quote($string) . ')';
231   '(' . join(' OR ', @where) . ')';
232 }
233
234 sub search_sql_addl_from {
235   'LEFT JOIN circuit_provider USING ( providernum ) '.
236   'LEFT JOIN circuit_type USING ( typenum )';
237 }
238
239 =back
240
241 =head1 SEE ALSO
242
243 L<FS::Record>
244
245 =cut
246
247 1;
248