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 ( $self->svcnum ) { #Case 2
53 $svcpart = $self->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 [ OBJECTS_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.
94 If an arrayref of FS::tablename objects (for example, FS::acct_snarf objects)
95 is passed as the optional second parameter, they will have their svcnum fields
96 set and will be inserted after this record, but before any exports are run.
102 local $FS::queue::jobnums = shift if @_;
103 my $objects = scalar(@_) ? shift : [];
106 local $SIG{HUP} = 'IGNORE';
107 local $SIG{INT} = 'IGNORE';
108 local $SIG{QUIT} = 'IGNORE';
109 local $SIG{TERM} = 'IGNORE';
110 local $SIG{TSTP} = 'IGNORE';
111 local $SIG{PIPE} = 'IGNORE';
113 my $oldAutoCommit = $FS::UID::AutoCommit;
114 local $FS::UID::AutoCommit = 0;
117 $error = $self->check;
118 return $error if $error;
120 my $svcnum = $self->svcnum;
122 #unless ( $svcnum ) {
123 if ( ! $svcnum || ! qsearchs('cust_svc',{'svcnum'=>$self->svcnum} ) ) {
124 $cust_svc = new FS::cust_svc ( {
125 #hua?# 'svcnum' => $svcnum,
126 'svcnum' => $self->svcnum,
127 'pkgnum' => $self->pkgnum,
128 'svcpart' => $self->svcpart,
130 $error = $cust_svc->insert;
132 $dbh->rollback if $oldAutoCommit;
135 $svcnum = $self->svcnum($cust_svc->svcnum);
137 $cust_svc = qsearchs('cust_svc',{'svcnum'=>$self->svcnum});
138 unless ( $cust_svc ) {
139 $dbh->rollback if $oldAutoCommit;
140 return "no cust_svc record found for svcnum ". $self->svcnum;
142 $self->pkgnum($cust_svc->pkgnum);
143 $self->svcpart($cust_svc->svcpart);
146 $error = $self->SUPER::insert;
148 $dbh->rollback if $oldAutoCommit;
152 foreach my $object ( @$objects ) {
153 $object->svcnum($self->svcnum);
154 $error = $object->insert;
156 $dbh->rollback if $oldAutoCommit;
162 unless ( $noexport_hack ) {
163 foreach my $part_export ( $self->cust_svc->part_svc->part_export ) {
164 my $error = $part_export->export_insert($self);
166 $dbh->rollback if $oldAutoCommit;
167 return "exporting to ". $part_export->exporttype.
168 " (transaction rolled back): $error";
173 $dbh->commit or die $dbh->errstr if $oldAutoCommit;
180 Deletes this account from the database. If there is an error, returns the
181 error, otherwise returns false.
183 The corresponding FS::cust_svc record will be deleted as well.
191 local $SIG{HUP} = 'IGNORE';
192 local $SIG{INT} = 'IGNORE';
193 local $SIG{QUIT} = 'IGNORE';
194 local $SIG{TERM} = 'IGNORE';
195 local $SIG{TSTP} = 'IGNORE';
196 local $SIG{PIPE} = 'IGNORE';
198 my $svcnum = $self->svcnum;
200 my $oldAutoCommit = $FS::UID::AutoCommit;
201 local $FS::UID::AutoCommit = 0;
204 $error = $self->SUPER::delete;
205 return $error if $error;
208 unless ( $noexport_hack ) {
209 foreach my $part_export ( $self->cust_svc->part_svc->part_export ) {
210 my $error = $part_export->export_delete($self);
212 $dbh->rollback if $oldAutoCommit;
213 return "exporting to ". $part_export->exporttype.
214 " (transaction rolled back): $error";
219 return $error if $error;
221 my $cust_svc = $self->cust_svc;
222 $error = $cust_svc->delete;
223 return $error if $error;
225 $dbh->commit or die $dbh->errstr if $oldAutoCommit;
230 =item replace OLD_RECORD
232 Replaces OLD_RECORD with this one. If there is an error, returns the error,
233 otherwise returns false.
238 my ($new, $old) = (shift, shift);
240 local $SIG{HUP} = 'IGNORE';
241 local $SIG{INT} = 'IGNORE';
242 local $SIG{QUIT} = 'IGNORE';
243 local $SIG{TERM} = 'IGNORE';
244 local $SIG{TSTP} = 'IGNORE';
245 local $SIG{PIPE} = 'IGNORE';
247 my $oldAutoCommit = $FS::UID::AutoCommit;
248 local $FS::UID::AutoCommit = 0;
251 my $error = $new->SUPER::replace($old);
253 $dbh->rollback if $oldAutoCommit;
258 unless ( $noexport_hack ) {
259 foreach my $part_export ( $new->cust_svc->part_svc->part_export ) {
260 my $error = $part_export->export_replace($new,$old);
262 $dbh->rollback if $oldAutoCommit;
263 return "error exporting to ". $part_export->exporttype.
264 " (transaction rolled back): $error";
269 $dbh->commit or die $dbh->errstr if $oldAutoCommit;
276 Sets any fixed fields for this service (see L<FS::part_svc>). If there is an
277 error, returns the error, otherwise returns the FS::part_svc object (use ref()
278 to test the return). Usually called by the check method.
289 Sets all fields to their defaults (see L<FS::part_svc>), overriding their
290 current values. If there is an error, returns the error, otherwise returns
291 the FS::part_svc object (use ref() to test the return).
307 $self->ut_numbern('svcnum')
309 return $error if $error;
313 if ( $self->svcnum ) {
314 my $cust_svc = $self->cust_svc;
315 return "Unknown svcnum" unless $cust_svc;
316 $svcpart = $cust_svc->svcpart;
318 $svcpart = $self->getfield('svcpart');
320 my $part_svc = qsearchs( 'part_svc', { 'svcpart' => $svcpart } );
321 return "Unkonwn svcpart" unless $part_svc;
323 #set default/fixed/whatever fields from part_svc
324 my $table = $self->table;
325 foreach my $field ( grep { $_ ne 'svcnum' } $self->fields ) {
326 my $part_svc_column = $part_svc->part_svc_column($field);
327 if ( $part_svc_column->columnflag eq $x ) {
328 $self->setfield( $field, $part_svc_column->columnvalue );
338 Returns the cust_svc record associated with this svc_ record, as a FS::cust_svc
339 object (see L<FS::cust_svc>).
345 qsearchs('cust_svc', { 'svcnum' => $self->svcnum } );
350 Runs export_suspend callbacks.
357 local $SIG{HUP} = 'IGNORE';
358 local $SIG{INT} = 'IGNORE';
359 local $SIG{QUIT} = 'IGNORE';
360 local $SIG{TERM} = 'IGNORE';
361 local $SIG{TSTP} = 'IGNORE';
362 local $SIG{PIPE} = 'IGNORE';
364 my $oldAutoCommit = $FS::UID::AutoCommit;
365 local $FS::UID::AutoCommit = 0;
369 unless ( $noexport_hack ) {
370 foreach my $part_export ( $self->cust_svc->part_svc->part_export ) {
371 my $error = $part_export->export_suspend($self);
373 $dbh->rollback if $oldAutoCommit;
374 return "error exporting to ". $part_export->exporttype.
375 " (transaction rolled back): $error";
380 $dbh->commit or die $dbh->errstr if $oldAutoCommit;
387 Runs export_unsuspend callbacks.
394 local $SIG{HUP} = 'IGNORE';
395 local $SIG{INT} = 'IGNORE';
396 local $SIG{QUIT} = 'IGNORE';
397 local $SIG{TERM} = 'IGNORE';
398 local $SIG{TSTP} = 'IGNORE';
399 local $SIG{PIPE} = 'IGNORE';
401 my $oldAutoCommit = $FS::UID::AutoCommit;
402 local $FS::UID::AutoCommit = 0;
406 unless ( $noexport_hack ) {
407 foreach my $part_export ( $self->cust_svc->part_svc->part_export ) {
408 my $error = $part_export->export_unsuspend($self);
410 $dbh->rollback if $oldAutoCommit;
411 return "error exporting to ". $part_export->exporttype.
412 " (transaction rolled back): $error";
417 $dbh->commit or die $dbh->errstr if $oldAutoCommit;
424 Stub - returns false (no error) so derived classes don't need to define these
425 methods. Called by the cancel method of FS::cust_pkg (see L<FS::cust_pkg>).
435 The setfixed method return value.
439 L<FS::Record>, L<FS::cust_svc>, L<FS::part_svc>, L<FS::cust_pkg>, schema.html
440 from the base documentation.