Documented some subtle behavior of the checkdest method.
[freeside.git] / FS / FS / cust_main_invoice.pm
1 package FS::cust_main_invoice;
2
3 use strict;
4 use vars qw(@ISA $conf $mydomain);
5 use Exporter;
6 use FS::Record qw( qsearchs );
7 use FS::Conf;
8 use FS::cust_main;
9 use FS::svc_acct;
10
11 @ISA = qw( FS::Record );
12
13 #ask FS::UID to run this stuff for us later
14 $FS::UID::callback{'FS::cust_main_invoice'} = sub { 
15   $conf = new FS::Conf;
16   $mydomain = $conf->config('domain');
17 };
18
19 =head1 NAME
20
21 FS::cust_main_invoice - Object methods for cust_main_invoice records
22
23 =head1 SYNOPSIS
24
25   use FS::cust_main_invoice;
26
27   $record = new FS::cust_main_invoice \%hash;
28   $record = new FS::cust_main_invoice { 'column' => 'value' };
29
30   $error = $record->insert;
31
32   $error = $new_record->replace($old_record);
33
34   $error = $record->delete;
35
36   $error = $record->check;
37
38   $email_address = $record->address;
39
40 =head1 DESCRIPTION
41
42 An FS::cust_main_invoice object represents an invoice destination.  FS::cust_main_invoice inherits from
43 FS::Record.  The following fields are currently supported:
44
45 =over 4
46
47 =item destnum - primary key
48
49 =item custnum - customer (see L<FS::cust_main>)
50
51 =item dest - Invoice destination: If numeric, a svcnum (see L<FS::svc_acct>), if string, a literal email address, or `POST' to enable mailing (the default if no cust_main_invoice records exist)
52
53 =back
54
55 =head1 METHODS
56
57 =over 4
58
59 =item new HASHREF
60
61 Creates a new invoice destination.  To add the invoice destination to the database, see L<"insert">.
62
63 Note that this stores the hash reference, not a distinct copy of the hash it
64 points to.  You can ask the object for a copy with the I<hash> method.
65
66 =cut
67
68 sub table { 'cust_main_invoice'; }
69
70 =item insert
71
72 Adds this record to the database.  If there is an error, returns the error,
73 otherwise returns false.
74
75 =item delete
76
77 Delete this record from the database.
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 =cut
85
86 sub replace {
87   my ( $new, $old ) = ( shift, shift );
88
89   return "Can't change custnum!" unless $old->custnum == $new->custnum;
90
91   $new->SUPER::replace;
92 }
93
94
95 =item check
96
97 Checks all fields to make sure this is a valid invoice destination.  If there is
98 an error, returns the error, otherwise returns false.  Called by the insert
99 and repalce methods.
100
101 =cut
102
103 sub check {
104   my $self = shift;
105
106   my $error = $self->ut_numbern('destnum')
107            || $self->ut_number('custnum')
108            || $self->checkdest;
109   ;
110   return $error if $error;
111
112   return "Unknown customer"
113     unless qsearchs('cust_main',{ 'custnum' => $self->custnum });
114
115   ''; #noerror
116 }
117
118 =item checkdest
119
120 Checks the dest field only.  If it finds that the account ends in the
121 same domain configured in the configuration files, it will change the
122 invoice destination from an email address to a service number instead.
123
124 =cut
125
126 sub checkdest { 
127   my $self = shift;
128
129   my $error = $self->ut_text('dest');
130   return $error if $error;
131
132   if ( $self->dest eq 'POST' ) {
133     #contemplate our navel
134   } elsif ( $self->dest =~ /^(\d+)$/ ) {
135     return "Unknown local account (specified by svcnum)"
136       unless qsearchs( 'svc_acct', { 'svcnum' => $self->dest } );
137   } elsif ( $self->dest =~ /^([\w\.\-]+)\@(([\w\.\-]+\.)+\w+)$/ ) {
138     my($user, $domain) = ($1, $2);
139     if ( $domain eq $mydomain ) {
140       my $svc_acct = qsearchs( 'svc_acct', { 'username' => $user } );
141       return "Unknown local account (specified literally)" unless $svc_acct;
142       $svc_acct->svcnum =~ /^(\d+)$/ or die "Non-numeric svcnum?!";
143       $self->dest($1);
144     }
145   } else {
146     return "Illegal destination!";
147   }
148
149   ''; #no error
150 }
151
152 =item address
153
154 Returns the literal email address for this record (or `POST').
155
156 =cut
157
158 sub address {
159   my $self = shift;
160   if ( $self->dest =~ /(\d+)$/ ) {
161     my $svc_acct = qsearchs( 'svc_acct', { 'svcnum' => $1 } );
162     $svc_acct->username . '@' . $mydomain;
163   } else {
164     $self->dest;
165   }
166 }
167
168 =back
169
170 =head1 VERSION
171
172 $Id: cust_main_invoice.pm,v 1.3 2001-07-27 06:17:46 thalakan Exp $
173
174 =head1 BUGS
175
176 =head1 SEE ALSO
177
178 L<FS::Record>, L<FS::cust_main>
179
180 =cut
181
182 1;
183