6 use FS::Record qw( qsearchs dbh );
14 use FS::domain_record;
16 @ISA = qw( FS::Record );
20 my ( $hashref, $cache ) = @_;
21 if ( $hashref->{'username'} ) {
22 $self->{'_svc_acct'} = FS::svc_acct->new($hashref, '');
24 if ( $hashref->{'svc'} ) {
25 $self->{'_svcpart'} = FS::part_svc->new($hashref);
31 FS::cust_svc - Object method for cust_svc objects
37 $record = new FS::cust_svc \%hash
38 $record = new FS::cust_svc { 'column' => 'value' };
40 $error = $record->insert;
42 $error = $new_record->replace($old_record);
44 $error = $record->delete;
46 $error = $record->check;
48 ($label, $value) = $record->label;
52 An FS::cust_svc represents a service. FS::cust_svc inherits from FS::Record.
53 The following fields are currently supported:
57 =item svcnum - primary key (assigned automatically for new services)
59 =item pkgnum - Package (see L<FS::cust_pkg>)
61 =item svcpart - Service definition (see L<FS::part_svc>)
71 Creates a new service. To add the refund to the database, see L<"insert">.
72 Services are normally created by creating FS::svc_ objects (see
73 L<FS::svc_acct>, L<FS::svc_domain>, and L<FS::svc_forward>, among others).
77 sub table { 'cust_svc'; }
81 Adds this service to the database. If there is an error, returns the error,
82 otherwise returns false.
86 Deletes this service from the database. If there is an error, returns the
87 error, otherwise returns false.
89 Called by the cancel method of the package (see L<FS::cust_pkg>).
91 =item replace OLD_RECORD
93 Replaces the OLD_RECORD with this one in the database. If there is an error,
94 returns the error, otherwise returns false.
98 Checks all fields to make sure this is a valid service. If there is an error,
99 returns the error, otehrwise returns false. Called by the insert and
108 $self->ut_numbern('svcnum')
109 || $self->ut_numbern('pkgnum')
110 || $self->ut_number('svcpart')
112 return $error if $error;
114 return "Unknown pkgnum"
115 unless ! $self->pkgnum
116 || qsearchs( 'cust_pkg', { 'pkgnum' => $self->pkgnum } );
118 return "Unknown svcpart" unless
119 qsearchs( 'part_svc', { 'svcpart' => $self->svcpart } );
126 Returns the definition for this service, as a FS::part_svc object (see
134 ? $self->{'_svcpart'}
135 : qsearchs( 'part_svc', { 'svcpart' => $self->svcpart } );
140 Returns the definition for this service, as a FS::part_svc object (see
147 qsearchs( 'cust_pkg', { 'pkgnum' => $self->pkgnum } );
152 Returns a list consisting of:
153 - The name of this service (from part_svc)
154 - A meaningful identifier (username, domain, or mail alias)
155 - The table name (i.e. svc_domain) for this service
161 my $svcdb = $self->part_svc->svcdb;
162 my $svc_x = $self->svc_x
163 or die "can't find $svcdb.svcnum ". $self->svcnum;
165 if ( $svcdb eq 'svc_acct' ) {
166 $tag = $svc_x->email;
167 } elsif ( $svcdb eq 'svc_acct_sm' ) {
168 my $domuser = $svc_x->domuser eq '*' ? '(anything)' : $svc_x->domuser;
169 my $svc_domain = qsearchs ( 'svc_domain', { 'svcnum' => $svc_x->domsvc } );
170 my $domain = $svc_domain->domain;
171 $tag = "$domuser\@$domain";
172 } elsif ( $svcdb eq 'svc_forward' ) {
173 my $svc_acct = qsearchs( 'svc_acct', { 'svcnum' => $svc_x->srcsvc } );
174 $tag = $svc_acct->email. '->';
175 if ( $svc_x->dstsvc ) {
176 $svc_acct = qsearchs( 'svc_acct', { 'svcnum' => $svc_x->dstsvc } );
177 $tag .= $svc_acct->email;
181 } elsif ( $svcdb eq 'svc_domain' ) {
182 $tag = $svc_x->getfield('domain');
183 } elsif ( $svcdb eq 'svc_www' ) {
184 my $domain = qsearchs( 'domain_record', { 'recnum' => $svc_x->recnum } );
185 $tag = $domain->reczone;
187 cluck "warning: asked for label of unsupported svcdb; using svcnum";
188 $tag = $svc_x->getfield('svcnum');
190 $self->part_svc->svc, $tag, $svcdb;
195 Returns the FS::svc_XXX object for this service (i.e. an FS::svc_acct object or
196 FS::svc_domain object, etc.)
202 my $svcdb = $self->part_svc->svcdb;
203 if ( $svcdb eq 'svc_acct' && $self->{'_svc_acct'} ) {
204 $self->{'_svc_acct'};
206 qsearchs( $svcdb, { 'svcnum' => $self->svcnum } );
210 =item seconds_since TIMESTAMP
212 See L<FS::svc_acct/seconds_since>. Equivalent to
213 $cust_svc->svc_x->seconds_since, but more efficient. Meaningless for records
214 where B<svcdb> is not "svc_acct".
218 #note: implementation here, POD in FS::svc_acct
220 my($self, $since) = @_;
222 my $sth = $dbh->prepare(' SELECT SUM(logout-login) FROM session
225 AND logout IS NOT NULL'
226 ) or die $dbh->errstr;
227 $sth->execute($self->svcnum, $since) or die $sth->errstr;
228 $sth->fetchrow_arrayref->[0];
235 $Id: cust_svc.pm,v 1.9 2002-01-29 16:33:15 ivan Exp $
239 Behaviour of changing the svcpart of cust_svc records is undefined and should
240 possibly be prohibited, and pkg_svc records are not checked.
242 pkg_svc records are not checked in general (here).
244 Deleting this record doesn't check or delete the svc_* record associated
249 L<FS::Record>, L<FS::cust_pkg>, L<FS::part_svc>, L<FS::pkg_svc>,
250 schema.html from the base documentation