1 package FS::svc_Common;
4 use vars qw( @ISA $noexport_hack );
5 use FS::Record qw( qsearch qsearchs fields dbh );
10 @ISA = qw( FS::Record );
14 FS::svc_Common - Object method for all svc_ records
20 @ISA = qw( FS::svc_Common );
24 FS::svc_Common is intended as a base class for table-specific classes to
25 inherit from, i.e. FS::svc_acct. FS::svc_Common inherits from FS::Record.
35 # This restricts the fields based on part_svc_column and the svcpart of
36 # the service. There are four possible cases:
37 # 1. svcpart passed as part of the svc_x hash.
38 # 2. svcpart fetched via cust_svc based on svcnum.
39 # 3. No svcnum or svcpart. In this case, return ALL the fields with
40 # dbtable eq $self->table.
41 # 4. Called via "fields('svc_acct')" or something similar. In this case
42 # there is no $self object.
46 my @vfields = $self->SUPER::virtual_fields;
48 return @vfields unless (ref $self); # Case 4
50 if ($self->svcpart) { # Case 1
51 $svcpart = $self->svcpart;
52 } elsif (my $cust_svc = $self->cust_svc) { # Case 2
53 $svcpart = $cust_svc->svcpart;
58 if ($svcpart) { #Cases 1 and 2
59 my %flags = map { $_->columnname, $_->columnflag } (
60 qsearch ('part_svc_column', { svcpart => $svcpart } )
62 return grep { not ($flags{$_} eq 'X') } @vfields;
71 Checks the validity of fields in this record.
73 At present, this does nothing but call FS::Record::check (which, in turn,
74 does nothing but run virtual field checks).
83 =item insert [ JOBNUM_ARRAYREF ]
85 Adds this record to the database. If there is an error, returns the error,
86 otherwise returns false.
88 The additional fields pkgnum and svcpart (see L<FS::cust_svc>) should be
89 defined. An FS::cust_svc record will be created and inserted.
91 If an arrayref is passed as parameter, the B<jobnum>s of any export jobs will
92 be added to the array.
98 local $FS::queue::jobnums = shift if @_;
101 local $SIG{HUP} = 'IGNORE';
102 local $SIG{INT} = 'IGNORE';
103 local $SIG{QUIT} = 'IGNORE';
104 local $SIG{TERM} = 'IGNORE';
105 local $SIG{TSTP} = 'IGNORE';
106 local $SIG{PIPE} = 'IGNORE';
108 my $oldAutoCommit = $FS::UID::AutoCommit;
109 local $FS::UID::AutoCommit = 0;
112 $error = $self->check;
113 return $error if $error;
115 my $svcnum = $self->svcnum;
118 $cust_svc = new FS::cust_svc ( {
119 #hua?# 'svcnum' => $svcnum,
120 'pkgnum' => $self->pkgnum,
121 'svcpart' => $self->svcpart,
123 $error = $cust_svc->insert;
125 $dbh->rollback if $oldAutoCommit;
128 $svcnum = $self->svcnum($cust_svc->svcnum);
130 $cust_svc = qsearchs('cust_svc',{'svcnum'=>$self->svcnum});
131 unless ( $cust_svc ) {
132 $dbh->rollback if $oldAutoCommit;
133 return "no cust_svc record found for svcnum ". $self->svcnum;
135 $self->pkgnum($cust_svc->pkgnum);
136 $self->svcpart($cust_svc->svcpart);
139 $error = $self->SUPER::insert;
141 $dbh->rollback if $oldAutoCommit;
146 unless ( $noexport_hack ) {
147 foreach my $part_export ( $self->cust_svc->part_svc->part_export ) {
148 my $error = $part_export->export_insert($self);
150 $dbh->rollback if $oldAutoCommit;
151 return "exporting to ". $part_export->exporttype.
152 " (transaction rolled back): $error";
157 $dbh->commit or die $dbh->errstr if $oldAutoCommit;
164 Deletes this account from the database. If there is an error, returns the
165 error, otherwise returns false.
167 The corresponding FS::cust_svc record will be deleted as well.
175 local $SIG{HUP} = 'IGNORE';
176 local $SIG{INT} = 'IGNORE';
177 local $SIG{QUIT} = 'IGNORE';
178 local $SIG{TERM} = 'IGNORE';
179 local $SIG{TSTP} = 'IGNORE';
180 local $SIG{PIPE} = 'IGNORE';
182 my $svcnum = $self->svcnum;
184 my $oldAutoCommit = $FS::UID::AutoCommit;
185 local $FS::UID::AutoCommit = 0;
188 $error = $self->SUPER::delete;
189 return $error if $error;
192 unless ( $noexport_hack ) {
193 foreach my $part_export ( $self->cust_svc->part_svc->part_export ) {
194 my $error = $part_export->export_delete($self);
196 $dbh->rollback if $oldAutoCommit;
197 return "exporting to ". $part_export->exporttype.
198 " (transaction rolled back): $error";
203 return $error if $error;
205 my $cust_svc = $self->cust_svc;
206 $error = $cust_svc->delete;
207 return $error if $error;
209 $dbh->commit or die $dbh->errstr if $oldAutoCommit;
214 =item replace OLD_RECORD
216 Replaces OLD_RECORD with this one. If there is an error, returns the error,
217 otherwise returns false.
222 my ($new, $old) = (shift, shift);
224 local $SIG{HUP} = 'IGNORE';
225 local $SIG{INT} = 'IGNORE';
226 local $SIG{QUIT} = 'IGNORE';
227 local $SIG{TERM} = 'IGNORE';
228 local $SIG{TSTP} = 'IGNORE';
229 local $SIG{PIPE} = 'IGNORE';
231 my $oldAutoCommit = $FS::UID::AutoCommit;
232 local $FS::UID::AutoCommit = 0;
235 my $error = $new->SUPER::replace($old);
237 $dbh->rollback if $oldAutoCommit;
242 unless ( $noexport_hack ) {
243 foreach my $part_export ( $new->cust_svc->part_svc->part_export ) {
244 my $error = $part_export->export_replace($new,$old);
246 $dbh->rollback if $oldAutoCommit;
247 return "error exporting to ". $part_export->exporttype.
248 " (transaction rolled back): $error";
253 $dbh->commit or die $dbh->errstr if $oldAutoCommit;
260 Sets any fixed fields for this service (see L<FS::part_svc>). If there is an
261 error, returns the error, otherwise returns the FS::part_svc object (use ref()
262 to test the return). Usually called by the check method.
273 Sets all fields to their defaults (see L<FS::part_svc>), overriding their
274 current values. If there is an error, returns the error, otherwise returns
275 the FS::part_svc object (use ref() to test the return).
291 $self->ut_numbern('svcnum')
293 return $error if $error;
297 if ( $self->svcnum ) {
298 my $cust_svc = $self->cust_svc;
299 return "Unknown svcnum" unless $cust_svc;
300 $svcpart = $cust_svc->svcpart;
302 $svcpart = $self->getfield('svcpart');
304 my $part_svc = qsearchs( 'part_svc', { 'svcpart' => $svcpart } );
305 return "Unkonwn svcpart" unless $part_svc;
307 #set default/fixed/whatever fields from part_svc
308 my $table = $self->table;
309 foreach my $field ( grep { $_ ne 'svcnum' } $self->fields ) {
310 my $part_svc_column = $part_svc->part_svc_column($field);
311 if ( $part_svc_column->columnflag eq $x ) {
312 $self->setfield( $field, $part_svc_column->columnvalue );
322 Returns the cust_svc record associated with this svc_ record, as a FS::cust_svc
323 object (see L<FS::cust_svc>).
329 qsearchs('cust_svc', { 'svcnum' => $self->svcnum } );
334 Runs export_suspend callbacks.
341 local $SIG{HUP} = 'IGNORE';
342 local $SIG{INT} = 'IGNORE';
343 local $SIG{QUIT} = 'IGNORE';
344 local $SIG{TERM} = 'IGNORE';
345 local $SIG{TSTP} = 'IGNORE';
346 local $SIG{PIPE} = 'IGNORE';
348 my $oldAutoCommit = $FS::UID::AutoCommit;
349 local $FS::UID::AutoCommit = 0;
353 unless ( $noexport_hack ) {
354 foreach my $part_export ( $self->cust_svc->part_svc->part_export ) {
355 my $error = $part_export->export_suspend($self);
357 $dbh->rollback if $oldAutoCommit;
358 return "error exporting to ". $part_export->exporttype.
359 " (transaction rolled back): $error";
364 $dbh->commit or die $dbh->errstr if $oldAutoCommit;
371 Runs export_unsuspend callbacks.
378 local $SIG{HUP} = 'IGNORE';
379 local $SIG{INT} = 'IGNORE';
380 local $SIG{QUIT} = 'IGNORE';
381 local $SIG{TERM} = 'IGNORE';
382 local $SIG{TSTP} = 'IGNORE';
383 local $SIG{PIPE} = 'IGNORE';
385 my $oldAutoCommit = $FS::UID::AutoCommit;
386 local $FS::UID::AutoCommit = 0;
390 unless ( $noexport_hack ) {
391 foreach my $part_export ( $self->cust_svc->part_svc->part_export ) {
392 my $error = $part_export->export_unsuspend($self);
394 $dbh->rollback if $oldAutoCommit;
395 return "error exporting to ". $part_export->exporttype.
396 " (transaction rolled back): $error";
401 $dbh->commit or die $dbh->errstr if $oldAutoCommit;
408 Stub - returns false (no error) so derived classes don't need to define these
409 methods. Called by the cancel method of FS::cust_pkg (see L<FS::cust_pkg>).
419 $Id: svc_Common.pm,v 1.13 2003-08-05 00:20:47 khoff Exp $
423 The setfixed method return value.
427 L<FS::Record>, L<FS::cust_svc>, L<FS::part_svc>, L<FS::cust_pkg>, schema.html
428 from the base documentation.