2 use base qw(FS::Password_Mixin
6 use vars qw( $conf $DEBUG $me );
8 use FS::Record qw( qsearch qsearchs dbh );
15 $me = '[FS::svc_dsl]';
17 FS::UID->install_callback( sub {
24 FS::svc_dsl - Object methods for svc_dsl records
30 $record = new FS::svc_dsl \%hash;
31 $record = new FS::svc_dsl { 'column' => 'value' };
33 $error = $record->insert;
35 $error = $new_record->replace($old_record);
37 $error = $record->delete;
39 $error = $record->check;
41 $error = $record->suspend;
43 $error = $record->unsuspend;
45 $error = $record->cancel;
49 An FS::svc_dsl object represents a DSL service. FS::svc_dsl inherits from
50 FS::svc_Common. The following fields are currently supported:
54 =item svcnum - Primary key (assigned automatcially for new DSL))
56 =item pushed - Time DSL order pushed to vendor/telco, if applicable
58 =item desired_due_date - Desired Due Date
60 =item due_date - Due Date
62 =item vendor_order_id - Vendor/telco DSL order #
64 =item vendor_order_type
66 Vendor/telco DSL order type (e.g. (M)ove, (A)dd, (C)hange, (D)elete, or similar)
68 =item vendor_order_status
70 Vendor/telco DSL order status (e.g. (N)ew, (A)ssigned, (R)ejected, (M)revised,
71 (C)ompleted, (X)cancelled, or similar)
73 =item first - End-user first name
75 =item last - End-user last name
77 =item company - End-user company name
79 =item phonenum - DSL Telephone Number
81 =item gateway_access_number - Gateway access number, if different
83 =item loop_type - Loop-type - vendor/telco-specific
85 =item local_voice_provider - Local Voice Provider's name
87 =item circuitnum - Circuit #
93 =item rate_band - Rate Band
103 Ikano-specific fields, do not use otherwise
105 =item username - if outsourced PPPoE/RADIUS, username
107 =item password - if outsourced PPPoE/RADIUS, password
109 =item monitored - Order is monitored (auto-pull/sync), either Y or blank
111 =item last_pull - time of last data pull from vendor/telco
122 Creates a new DSL. To add the DSL to the database, see L<"insert">.
124 Note that this stores the hash reference, not a distinct copy of the hash it
125 points to. You can ask the object for a copy with the I<hash> method.
129 # the new method can be inherited from FS::Record, if a table method is defined
132 my %dis1 = ( disable_default=>1, disable_fixed=>1, disable_inventory=>1, disable_select=>1 );
133 my %dis2 = ( disable_inventory=>1, disable_select=>1 );
137 'name_plural' => 'DSLs',
138 'lcname_plural' => 'DSLs',
139 'sorts' => [ 'phonenum' ],
140 'display_weight' => 55,
141 'cancel_weight' => 75,
142 'ip_field' => 'staticips',
144 'pushed' => { label => 'Pushed',
145 type => 'disabled' },
146 'desired_due_date' => { label => 'Desired Due Date', %dis2, },
147 'due_date' => { label => 'Due Date', %dis2, },
148 'vendor_order_id' => { label => 'Vendor Order ID', %dis2, },
149 'vendor_qual_id' => { label => 'Vendor Qualification ID',
150 type => 'disabled' },
151 'vendor_order_type' => { label => 'Vendor Order Type',
152 disable_inventory => 1, },
153 'vendor_order_status' => { label => 'Vendor Order Status',
154 disable_inventory => 1, },
155 'first' => { label => 'First Name', %dis2, },
156 'last' => { label => 'Last Name', %dis2, },
157 'company' => { label => 'Company Name', %dis2, },
158 'phonenum' => { label => 'Service Telephone Number', },
159 'gateway_access_number' => { label => 'Gateway Access Number'.
160 ' (if different)', },
161 'loop_type' => { label => 'Loop Type',
162 disable_inventory => 1, },
163 'local_voice_provider' => { label => 'Local Voice Provider',
164 disable_inventory => 1, },
165 'circuitnum' => { label => 'Circuit #', },
166 'rate_band' => { label => 'Rate Band',
167 disable_inventory => 1, },
168 'vpi' => { label => 'VPI',
169 disable_inventory => 1 },
170 'vci' => { label => 'VCI',
171 disable_inventory => 1 },
172 'isp_chg' => { label => 'ISP Changing?',
175 'isp_prev' => { label => 'Current or Previous ISP',
176 disable_inventory => 1, },
177 'username' => { label => 'PPPoE Username',
179 'password' => { label => 'PPPoE Password', %dis2 },
180 'staticips' => { label => 'Static IPs', %dis1 },
181 'monitored' => { label => 'Monitored',
182 type => 'checkbox', %dis2 },
183 'last_pull' => { label => 'Last Pull',
184 type => 'disabled' },
189 sub table { 'svc_dsl'; }
193 return $self->phonenum if $self->phonenum;
194 return $self->username if $self->username;
195 return $self->vendor_order_id if $self->vendor_order_id;
196 return $self->svcnum;
201 Returns the set of FS::dsl_notes associated with this service
206 qsearch( 'dsl_note', { 'svcnum' => $self->svcnum } );
211 Adds this record to the database. If there is an error, returns the error,
212 otherwise returns false.
219 my $oldAutoCommit = $FS::UID::AutoCommit;
220 local $FS::UID::AutoCommit = 0;
222 my $error = $self->SUPER::insert(@_);
223 if ( length($self->password) ) {
224 $error ||= $self->insert_password_history;
228 $dbh->rollback if $oldAutoCommit;
232 $dbh->commit if $oldAutoCommit;
238 Delete this record from the database.
242 # the delete method can be inherited from FS::Record
244 =item replace OLD_RECORD
246 Replaces the OLD_RECORD with this one in the database. If there is an error,
247 returns the error, otherwise returns false.
253 my $old = shift || $new->replace_old;
255 my $oldAutoCommit = $FS::UID::AutoCommit;
256 local $FS::UID::AutoCommit = 0;
258 my $error = $new->SUPER::replace($old, @_);
259 if ( $old->password ne $new->password ) {
260 $error ||= $new->insert_password_history;
264 $dbh->rollback if $oldAutoCommit;
268 $dbh->commit if $oldAutoCommit;
272 # the replace method can be inherited from FS::Record
276 Checks all fields to make sure this is a valid DSL. If there is
277 an error, returns the error, otherwise returns false. Called by the insert
282 # the check method should currently be supplied - FS::Record contains some
283 # data checking routines
289 $self->ut_numbern('svcnum')
290 || $self->ut_numbern('pushed')
291 || $self->ut_numbern('desired_due_date')
292 || $self->ut_numbern('due_date')
293 || $self->ut_textn('vendor_order_id')
294 || $self->ut_textn('vendor_qual_id')
295 || $self->ut_alphan('vendor_order_type')
296 || $self->ut_alphan('vendor_order_status')
297 || $self->ut_textn('first')
298 || $self->ut_textn('last')
299 || $self->ut_textn('company')
300 || $self->ut_numbern('phonenum')
301 || $self->ut_numbern('gateway_access_number')
302 || $self->ut_alphasn('loop_type')
303 || $self->ut_textn('local_voice_provider')
304 || $self->ut_textn('circuitnum')
305 || $self->ut_textn('rate_band')
306 || $self->ut_numbern('vpi')
307 || $self->ut_numbern('vci')
308 || $self->ut_alphan('isp_chg')
309 || $self->ut_textn('isp_prev')
310 || $self->ut_textn('username')
311 || $self->ut_textn('password')
312 || $self->ut_textn('staticips')
313 || $self->ut_enum('monitored', [ '', 'Y' ])
314 || $self->ut_numbern('last_pull')
316 return $error if $error;
318 $self->gateway_access_number('')
319 if $self->phonenum && $self->phonenum eq $self->gateway_access_number;
324 =item gateway_access_or_phonenum
328 sub gateway_access_or_phonenum {
330 $self->gateway_access_number || $self->phonenum;
335 Returns the MAC addresses associated with this DSL service, as FS::dsl_device
342 qsearch('dsl_device', { 'svcnum' => $self->svcnum });
345 sub predelete_hook_first {
347 my @exports = $self->part_svc->part_export_dsl_pull;
348 return 'More than one DSL-pulling export attached' if scalar(@exports) > 1;
349 if ( scalar(@exports) == 1 ) {
350 my $export = $exports[0];
351 return $export->dsl_pull($self);
358 my @notes = $self->notes;
359 foreach my $note ( @notes ) {
360 my $error = $note->delete;
361 return $error if $error;
366 # password_history compatibility
370 $self->get('password');
373 sub _password_encoding { 'plain'; }
379 L<FS::svc_Common>, edit/part_svc.cgi from an installed web interface,
380 export.html from the base documentation, L<FS::Record>, L<FS::Conf>,
381 L<FS::cust_svc>, L<FS::part_svc>, L<FS::cust_pkg>, L<FS::queue>,
382 L<freeside-queued>, schema.html from the base documentation.