stray closing /TABLE in the no-ticket case
[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 - 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 =back
79
80 =head1 METHODS
81
82 =over 4
83
84 =item new HASHREF
85
86 Creates a new circuit service.  To add the record to the database, see 
87 L<"insert">.
88
89 =cut
90
91 sub table { 'svc_circuit'; }
92
93 sub table_info {
94   my %dis = ( disable_default => 1, disable_fixed => 1,
95               disabled_inventory => 1, disable_select => 1 );
96
97   tie my %fields, 'Tie::IxHash', (
98     'svcnum'            => 'Service',
99     'providernum'       => {
100                               label         => 'Provider',
101                               type          => 'select',
102                               select_table  => 'circuit_provider',
103                               select_key    => 'providernum',
104                               select_label  => 'provider',
105                               disable_inventory => 1,
106                            },
107     'typenum'           => {
108                               label         => 'Circuit type',
109                               type          => 'select',
110                               select_table  => 'circuit_type',
111                               select_key    => 'typenum',
112                               select_label  => 'typename',
113                               disable_inventory => 1,
114                            },
115     'termnum'           => {
116                               label         => 'Termination type',
117                               type          => 'select',
118                               select_table  => 'circuit_termination',
119                               select_key    => 'termnum',
120                               select_label  => 'termination',
121                               disable_inventory => 1,
122                            },
123     'circuit_id'        => { label => 'Circuit ID', %dis },
124     'desired_due_date'  => { label => 'Desired due date',
125                              %dis
126                            },
127     'due_date'          => { label => 'Due date',
128                              %dis
129                            },
130     'vendor_order_id'   => { label => 'Vendor order ID', %dis },
131     'vendor_qual_id'    => { label => 'Vendor qualification ID', %dis },
132     'vendor_order_type' => {
133                               label => 'Vendor order type',
134                               disable_inventory => 1
135                            }, # should be a select?
136     'vendor_order_status' => {
137                               label => 'Vendor order status',
138                               disable_inventory => 1
139                              }, # should also be a select?
140     'endpoint_ip_addr'  => {
141                               label => 'Endpoint IP address',
142                            },
143     'endpoint_mac_addr' => {
144                               label => 'Endpoint MAC address',
145                               type => 'input-mac_addr',
146                               disable_inventory => 1,
147                            },
148   );
149   return {
150     'name'              => 'Circuit',
151     'name_plural'       => 'Circuits',
152     'longname_plural'   => 'Voice and data circuit services',
153     'display_weight'    => 72,
154     'cancel_weight'     => 85, # after svc_phone
155     'fields'            => \%fields,
156   };
157 }
158
159 =item insert
160
161 Adds this record to the database.  If there is an error, returns the error,
162 otherwise returns false.
163
164 =item delete
165
166 Delete this record from the database.
167
168 =item replace OLD_RECORD
169
170 Replaces the OLD_RECORD with this one in the database.  If there is an error,
171 returns the error, otherwise returns false.
172
173 =item check
174
175 Checks all fields to make sure this is a valid service.  If there is
176 an error, returns the error, otherwise returns false.  Called by the insert
177 and replace methods.
178
179 =cut
180
181 sub check {
182   my $self = shift;
183
184   my $mac_addr = uc($self->get('endpoint_mac_addr'));
185   $mac_addr =~ s/[\W_]//g;
186   $self->set('endpoint_mac_addr', $mac_addr);
187
188   my $error = 
189     $self->ut_numbern('svcnum')
190     || $self->ut_number('typenum')
191     || $self->ut_number('providernum')
192     || $self->ut_text('circuit_id')
193     || $self->ut_numbern('desired_due_date')
194     || $self->ut_numbern('due_date')
195     || $self->ut_textn('vendor_order_id')
196     || $self->ut_textn('vendor_qual_id')
197     || $self->ut_textn('vendor_order_type')
198     || $self->ut_textn('vendor_order_status')
199     || $self->ut_ipn('endpoint_ip_addr')
200     || $self->ut_textn('endpoint_mac_addr')
201   ;
202
203   # no canonical values yet for vendor_order_status or _type
204
205   return $error if $error;
206
207   $self->SUPER::check;
208 }
209
210 =item label
211
212 Returns the circuit ID.
213
214 =cut
215
216 sub label {
217   my $self = shift;
218   $self->get('circuit_id');
219 }
220
221 sub search_sql {
222   my ($class, $string) = @_;
223   my @where = ();
224   push @where, 'LOWER(svc_circuit.circuit_id) = LOWER(' . dbh->quote($string) . ')';
225   push @where, 'LOWER(circuit_provider.provider) = LOWER(' . dbh->quote($string) . ')';
226   push @where, 'LOWER(circuit_type.typename) = LOWER(' . dbh->quote($string) . ')';
227   '(' . join(' OR ', @where) . ')';
228 }
229
230 sub search_sql_addl_from {
231   'LEFT JOIN circuit_provider USING ( providernum ) '.
232   'LEFT JOIN circuit_type USING ( typenum )';
233 }
234
235 =back
236
237 =head1 SEE ALSO
238
239 L<FS::Record>
240
241 =cut
242
243 1;
244