- web interface for hourly account charges!
[freeside.git] / FS / FS / cust_svc.pm
index cbc4d91..541f0c8 100644 (file)
@@ -3,16 +3,29 @@ package FS::cust_svc;
 use strict;
 use vars qw( @ISA );
 use Carp qw( cluck );
-use FS::Record qw( qsearchs );
+use FS::Record qw( qsearchs dbh );
 use FS::cust_pkg;
 use FS::part_pkg;
 use FS::part_svc;
 use FS::svc_acct;
 use FS::svc_acct_sm;
 use FS::svc_domain;
+use FS::svc_forward;
+use FS::domain_record;
 
 @ISA = qw( FS::Record );
 
+sub _cache {
+  my $self = shift;
+  my ( $hashref, $cache ) = @_;
+  if ( $hashref->{'username'} ) {
+    $self->{'_svc_acct'} = FS::svc_acct->new($hashref, '');
+  }
+  if ( $hashref->{'svc'} ) {
+    $self->{'_svcpart'} = FS::part_svc->new($hashref);
+  }
+}
+
 =head1 NAME
 
 FS::cust_svc - Object method for cust_svc objects
@@ -57,7 +70,7 @@ The following fields are currently supported:
 
 Creates a new service.  To add the refund to the database, see L<"insert">.
 Services are normally created by creating FS::svc_ objects (see
-L<FS::svc_acct>, L<FS::svc_domain>, and L<FS::svc_acct_sm>, among others).
+L<FS::svc_acct>, L<FS::svc_domain>, and L<FS::svc_forward>, among others).
 
 =cut
 
@@ -108,6 +121,32 @@ sub check {
   ''; #no error
 }
 
+=item part_svc
+
+Returns the definition for this service, as a FS::part_svc object (see
+L<FS::part_svc>).
+
+=cut
+
+sub part_svc {
+  my $self = shift;
+  $self->{'_svcpart'}
+    ? $self->{'_svcpart'}
+    : qsearchs( 'part_svc', { 'svcpart' => $self->svcpart } );
+}
+
+=item cust_pkg
+
+Returns the definition for this service, as a FS::part_svc object (see
+L<FS::part_svc>).
+
+=cut
+
+sub cust_pkg {
+  my $self = shift;
+  qsearchs( 'cust_pkg', { 'pkgnum' => $self->pkgnum } );
+}
+
 =item label
 
 Returns a list consisting of:
@@ -119,32 +158,81 @@ Returns a list consisting of:
 
 sub label {
   my $self = shift;
-  my $part_svc = qsearchs( 'part_svc', { 'svcpart' => $self->svcpart } );
-  my $svcdb = $part_svc->svcdb;
-  my $svc_x = qsearchs( $svcdb, { 'svcnum' => $self->svcnum } );
-  my $svc = $part_svc->svc;
+  my $svcdb = $self->part_svc->svcdb;
+  my $svc_x = $self->svc_x
+    or die "can't find $svcdb.svcnum ". $self->svcnum;
   my $tag;
   if ( $svcdb eq 'svc_acct' ) {
-    $tag = $svc_x->getfield('username');
+    $tag = $svc_x->email;
   } elsif ( $svcdb eq 'svc_acct_sm' ) {
     my $domuser = $svc_x->domuser eq '*' ? '(anything)' : $svc_x->domuser;
     my $svc_domain = qsearchs ( 'svc_domain', { 'svcnum' => $svc_x->domsvc } );
     my $domain = $svc_domain->domain;
     $tag = "$domuser\@$domain";
+  } elsif ( $svcdb eq 'svc_forward' ) {
+    my $svc_acct = qsearchs( 'svc_acct', { 'svcnum' => $svc_x->srcsvc } );
+    $tag = $svc_acct->email. '->';
+    if ( $svc_x->dstsvc ) {
+      $svc_acct = qsearchs( 'svc_acct', { 'svcnum' => $svc_x->dstsvc } );
+      $tag .= $svc_acct->email;
+    } else {
+      $tag .= $svc_x->dst;
+    }
   } elsif ( $svcdb eq 'svc_domain' ) {
     $tag = $svc_x->getfield('domain');
+  } elsif ( $svcdb eq 'svc_www' ) {
+    my $domain = qsearchs( 'domain_record', { 'recnum' => $svc_x->recnum } );
+    $tag = $domain->reczone;
   } else {
     cluck "warning: asked for label of unsupported svcdb; using svcnum";
     $tag = $svc_x->getfield('svcnum');
   }
-  $svc, $tag, $svcdb;
+  $self->part_svc->svc, $tag, $svcdb;
+}
+
+=item svc_x
+
+Returns the FS::svc_XXX object for this service (i.e. an FS::svc_acct object or
+FS::svc_domain object, etc.)
+
+=cut
+
+sub svc_x {
+  my $self = shift;
+  my $svcdb = $self->part_svc->svcdb;
+  if ( $svcdb eq 'svc_acct' && $self->{'_svc_acct'} ) {
+    $self->{'_svc_acct'};
+  } else {
+    qsearchs( $svcdb, { 'svcnum' => $self->svcnum } );
+  }
+}
+
+=item seconds_since TIMESTAMP
+
+See L<FS::svc_acct/seconds_since>.  Equivalent to
+$cust_svc->svc_x->seconds_since, but more efficient.  Meaningless for records
+where B<svcdb> is not "svc_acct".
+
+=cut
+
+#note: implementation here, POD in FS::svc_acct
+sub seconds_since {
+  my($self, $since) = @_;
+  my $dbh = dbh;
+  my $sth = $dbh->prepare(' SELECT SUM(logout-login) FROM session
+                              WHERE svcnum = ?
+                                AND login >= ?
+                                AND logout IS NOT NULL'
+  ) or die $dbh->errstr;
+  $sth->execute($self->svcnum, $since) or die $sth->errstr;
+  $sth->fetchrow_arrayref->[0];
 }
 
 =back
 
 =head1 VERSION
 
-$Id: cust_svc.pm,v 1.1 1999-08-04 09:03:53 ivan Exp $
+$Id: cust_svc.pm,v 1.9 2002-01-29 16:33:15 ivan Exp $
 
 =head1 BUGS