added user interface for svc_forward and vpopmail support
[freeside.git] / FS / FS / cust_svc.pm
1 package FS::cust_svc;
2
3 use strict;
4 use vars qw( @ISA );
5 use Carp qw( cluck );
6 use FS::Record qw( qsearchs );
7 use FS::cust_pkg;
8 use FS::part_pkg;
9 use FS::part_svc;
10 use FS::svc_acct;
11 use FS::svc_acct_sm;
12 use FS::svc_domain;
13 use FS::svc_forward;
14
15 @ISA = qw( FS::Record );
16
17 =head1 NAME
18
19 FS::cust_svc - Object method for cust_svc objects
20
21 =head1 SYNOPSIS
22
23   use FS::cust_svc;
24
25   $record = new FS::cust_svc \%hash
26   $record = new FS::cust_svc { 'column' => 'value' };
27
28   $error = $record->insert;
29
30   $error = $new_record->replace($old_record);
31
32   $error = $record->delete;
33
34   $error = $record->check;
35
36   ($label, $value) = $record->label;
37
38 =head1 DESCRIPTION
39
40 An FS::cust_svc represents a service.  FS::cust_svc inherits from FS::Record.
41 The following fields are currently supported:
42
43 =over 4
44
45 =item svcnum - primary key (assigned automatically for new services)
46
47 =item pkgnum - Package (see L<FS::cust_pkg>)
48
49 =item svcpart - Service definition (see L<FS::part_svc>)
50
51 =back
52
53 =head1 METHODS
54
55 =over 4
56
57 =item new HASHREF
58
59 Creates a new service.  To add the refund to the database, see L<"insert">.
60 Services are normally created by creating FS::svc_ objects (see
61 L<FS::svc_acct>, L<FS::svc_domain>, and L<FS::svc_acct_sm>, among others).
62
63 =cut
64
65 sub table { 'cust_svc'; }
66
67 =item insert
68
69 Adds this service to the database.  If there is an error, returns the error,
70 otherwise returns false.
71
72 =item delete
73
74 Deletes this service from the database.  If there is an error, returns the
75 error, otherwise returns false.
76
77 Called by the cancel method of the package (see L<FS::cust_pkg>).
78
79 =item replace OLD_RECORD
80
81 Replaces the OLD_RECORD with this one in the database.  If there is an error,
82 returns the error, otherwise returns false.
83
84 =item check
85
86 Checks all fields to make sure this is a valid service.  If there is an error,
87 returns the error, otehrwise returns false.  Called by the insert and
88 replace methods.
89
90 =cut
91
92 sub check {
93   my $self = shift;
94
95   my $error =
96     $self->ut_numbern('svcnum')
97     || $self->ut_numbern('pkgnum')
98     || $self->ut_number('svcpart')
99   ;
100   return $error if $error;
101
102   return "Unknown pkgnum"
103     unless ! $self->pkgnum
104       || qsearchs( 'cust_pkg', { 'pkgnum' => $self->pkgnum } );
105
106   return "Unknown svcpart" unless
107     qsearchs( 'part_svc', { 'svcpart' => $self->svcpart } );
108
109   ''; #no error
110 }
111
112 =item label
113
114 Returns a list consisting of:
115 - The name of this service (from part_svc)
116 - A meaningful identifier (username, domain, or mail alias)
117 - The table name (i.e. svc_domain) for this service
118
119 =cut
120
121 sub label {
122   my $self = shift;
123   my $part_svc = qsearchs( 'part_svc', { 'svcpart' => $self->svcpart } );
124   my $svcdb = $part_svc->svcdb;
125   my $svc_x = qsearchs( $svcdb, { 'svcnum' => $self->svcnum } );
126   my $svc = $part_svc->svc;
127   my $tag;
128   if ( $svcdb eq 'svc_acct' ) {
129     $tag = $svc_x->getfield('username');
130   } elsif ( $svcdb eq 'svc_acct_sm' ) {
131     my $domuser = $svc_x->domuser eq '*' ? '(anything)' : $svc_x->domuser;
132     my $svc_domain = qsearchs ( 'svc_domain', { 'svcnum' => $svc_x->domsvc } );
133     my $domain = $svc_domain->domain;
134     $tag = "$domuser\@$domain";
135   } elsif ( $svcdb eq 'svc_forward' ) {
136     my $svc_acct = qsearchs ( 'svc_acct', { 'svcnum' => $svc_x->srcsvc } );
137     $tag = $svc_acct->email . '->';
138     if ($svc_x->dstsvc) {
139       $svc_acct = qsearchs ( 'svc_acct', { 'svcnum' => $svc_x->dstsvc } );
140       $tag .= $svc_acct->email;
141     }else{
142       $tag .= $svc_x->dst;
143     }
144   } elsif ( $svcdb eq 'svc_domain' ) {
145     $tag = $svc_x->getfield('domain');
146   } else {
147     cluck "warning: asked for label of unsupported svcdb; using svcnum";
148     $tag = $svc_x->getfield('svcnum');
149   }
150   $svc, $tag, $svcdb;
151 }
152
153 =back
154
155 =head1 VERSION
156
157 $Id: cust_svc.pm,v 1.2 2001-08-19 15:53:34 jeff Exp $
158
159 =head1 BUGS
160
161 Behaviour of changing the svcpart of cust_svc records is undefined and should
162 possibly be prohibited, and pkg_svc records are not checked.
163
164 pkg_svc records are not checked in general (here).
165
166 Deleting this record doesn't check or delete the svc_* record associated
167 with this record.
168
169 =head1 SEE ALSO
170
171 L<FS::Record>, L<FS::cust_pkg>, L<FS::part_svc>, L<FS::pkg_svc>, 
172 schema.html from the base documentation
173
174 =cut
175
176 1;
177