b1c35d76fc5223ebd92a6acaca0150eaa2393150
[freeside.git] / FS / FS / cust_pay.pm
1 package FS::cust_pay;
2
3 use strict;
4 use vars qw( @ISA );
5 use Business::CreditCard;
6 use FS::Record qw( dbh );
7 use FS::cust_bill;
8 use FS::cust_bill_pay;
9
10 @ISA = qw( FS::Record );
11
12 =head1 NAME
13
14 FS::cust_pay - Object methods for cust_pay objects
15
16 =head1 SYNOPSIS
17
18   use FS::cust_pay;
19
20   $record = new FS::cust_pay \%hash;
21   $record = new FS::cust_pay { 'column' => 'value' };
22
23   $error = $record->insert;
24
25   $error = $new_record->replace($old_record);
26
27   $error = $record->delete;
28
29   $error = $record->check;
30
31 =head1 DESCRIPTION
32
33 An FS::cust_pay object represents a payment; the transfer of money from a
34 customer.  FS::cust_pay inherits from FS::Record.  The following fields are
35 currently supported:
36
37 =over 4
38
39 =item paynum - primary key (assigned automatically for new payments)
40
41 =item paid - Amount of this payment
42
43 =item _date - specified as a UNIX timestamp; see L<perlfunc/"time">.  Also see
44 L<Time::Local> and L<Date::Parse> for conversion functions.
45
46 =item payby - `CARD' (credit cards), `BILL' (billing), or `COMP' (free)
47
48 =item payinfo - card number, P.O.#, or comp issuer (4-8 lowercase alphanumerics; think username)
49
50 =item paybatch - text field for tracking card processing
51
52 =back
53
54 =head1 METHODS
55
56 =over 4 
57
58 =item new HASHREF
59
60 Creates a new payment.  To add the payment to the databse, see L<"insert">.
61
62 =cut
63
64 sub table { 'cust_pay'; }
65
66 =item insert
67
68 Adds this payment to the database.
69
70 For backwards-compatibility and convenience, if the additional field invnum
71 is defined, an FS::cust_bill_pay record for the full amount of the payment
72 will be created.
73
74 =cut
75
76 sub insert {
77   my $self = shift;
78
79   local $SIG{HUP} = 'IGNORE';
80   local $SIG{INT} = 'IGNORE';
81   local $SIG{QUIT} = 'IGNORE';
82   local $SIG{TERM} = 'IGNORE';
83   local $SIG{TSTP} = 'IGNORE';
84   local $SIG{PIPE} = 'IGNORE';
85
86   my $oldAutoCommit = $FS::UID::AutoCommit;
87   local $FS::UID::AutoCommit = 0;
88   my $dbh = dbh;
89
90   my $error = $self->check;
91   return $error if $error;
92
93   $error = $self->SUPER::insert;
94   if ( $error ) {
95     $dbh->rollback if $oldAutoCommit;
96     return $error;
97   }
98
99   if ( $self->invnum ) {
100     my $cust_bill_pay = new FS::cust_bill_pay {
101       'invnum' => $self->invnum,
102       'paynum' => $self->paynum,
103       'amount' => $self->paid,
104       '_date'  => $self->_date,
105     };
106     $error = $cust_bill_pay->insert;
107     if ( $error ) {
108       $dbh->rollback if $oldAutoCommit;
109       return $error;
110     }
111   }
112
113   $dbh->commit or die $dbh->errstr if $oldAutoCommit;
114
115   '';
116
117 }
118
119 =item delete
120
121 Currently unimplemented (accounting reasons).
122
123 =cut
124
125 sub delete {
126   return "Can't (yet?) delete cust_pay records!";
127 }
128
129 =item replace OLD_RECORD
130
131 Currently unimplemented (accounting reasons).
132
133 =cut
134
135 sub replace {
136    return "Can't (yet?) modify cust_pay records!";
137 }
138
139 =item check
140
141 Checks all fields to make sure this is a valid payment.  If there is an error,
142 returns the error, otherwise returns false.  Called by the insert method.
143
144 =cut
145
146 sub check {
147   my $self = shift;
148
149   my $error =
150     $self->ut_numbern('paynum')
151     || $self->ut_money('paid')
152     || $self->ut_numbern('_date')
153     || $self->ut_textn('paybatch')
154   ;
155   return $error if $error;
156
157   $self->_date(time) unless $self->_date;
158
159   $self->payby =~ /^(CARD|BILL|COMP)$/ or return "Illegal payby";
160   $self->payby($1);
161
162   if ( $self->payby eq 'CARD' ) {
163     my $payinfo = $self->payinfo;
164     $payinfo =~ s/\D//g;
165     $self->payinfo($payinfo);
166     if ( $self->payinfo ) {
167       $self->payinfo =~ /^(\d{13,16})$/
168         or return "Illegal (mistyped?) credit card number (payinfo)";
169       $self->payinfo($1);
170       validate($self->payinfo) or return "Illegal credit card number";
171       return "Unknown card type" if cardtype($self->payinfo) eq "Unknown";
172     } else {
173       $self->payinfo('N/A');
174     }
175
176   } else {
177     $error = $self->ut_textn('payinfo');
178     return $error if $error;
179   }
180
181   ''; #no error
182
183 }
184
185 =back
186
187 =head1 VERSION
188
189 $Id: cust_pay.pm,v 1.4 2001-09-01 20:11:07 ivan Exp $
190
191 =head1 BUGS
192
193 Delete and replace methods.
194
195 =head1 SEE ALSO
196
197 L<FS::cust_bill_pay>, L<FS::cust_bill>, L<FS::Record>, schema.html from the
198 base documentation.
199
200 =cut
201
202 1;
203