This commit was generated by cvs2svn to compensate for changes in r6252,
[freeside.git] / FS / FS / cust_pay_pending.pm
1 package FS::cust_pay_pending;
2
3 use strict;
4 use vars qw( @ISA  @encrypted_fields );
5 use FS::Record qw( qsearch qsearchs );
6 use FS::payby;
7 use FS::payinfo_Mixin;
8 use FS::cust_main;
9 use FS::cust_pay;
10
11 @ISA = qw(FS::Record FS::payinfo_Mixin);
12
13 @encrypted_fields = ('payinfo');
14
15 =head1 NAME
16
17 FS::cust_pay_pending - Object methods for cust_pay_pending records
18
19 =head1 SYNOPSIS
20
21   use FS::cust_pay_pending;
22
23   $record = new FS::cust_pay_pending \%hash;
24   $record = new FS::cust_pay_pending { 'column' => 'value' };
25
26   $error = $record->insert;
27
28   $error = $new_record->replace($old_record);
29
30   $error = $record->delete;
31
32   $error = $record->check;
33
34 =head1 DESCRIPTION
35
36 An FS::cust_pay_pending object represents an pending payment.  It reflects 
37 local state through the multiple stages of processing a real-time transaction
38 with an external gateway.  FS::cust_pay_pending inherits from FS::Record.  The
39 following fields are currently supported:
40
41 =over 4
42
43 =item paypendingnum
44
45 Primary key
46
47 =item custnum
48
49 Customer (see L<FS::cust_main>)
50
51 =item paid
52
53 Amount of this payment
54
55 =item _date
56
57 Specified as a UNIX timestamp; see L<perlfunc/"time">.  Also see
58 L<Time::Local> and L<Date::Parse> for conversion functions.
59
60 =item payby
61
62 Payment Type (See L<FS::payinfo_Mixin> for valid payby values)
63
64 =item payinfo
65
66 Payment Information (See L<FS::payinfo_Mixin> for data format)
67
68 =item paymask
69
70 Masked payinfo (See L<FS::payinfo_Mixin> for how this works)
71
72 =item paydate
73
74 Expiration date
75
76 =item payunique
77
78 Unique identifer to prevent duplicate transactions.
79
80 =item status
81
82 Pending transaction status, one of the following:
83
84 =over 4
85
86 =item new
87
88 Aquires basic lock on payunique
89
90 =item pending
91
92 Transaction is pending with the gateway
93
94 =item authorized
95
96 Only used for two-stage transactions that require a separate capture step
97
98 =item captured
99
100 Transaction completed with payment gateway (sucessfully), not yet recorded in
101 the database
102
103 =item declined
104
105 Transaction completed with payment gateway (declined), not yet recorded in
106 the database
107
108 =item done
109
110 Transaction recorded in database
111
112 =back
113
114 =item statustext
115
116 Additional status information.
117
118 =cut
119
120 #=item cust_balance - 
121
122 =item paynum - 
123
124
125 =back
126
127 =head1 METHODS
128
129 =over 4
130
131 =item new HASHREF
132
133 Creates a new pending payment.  To add the pending payment to the database, see L<"insert">.
134
135 Note that this stores the hash reference, not a distinct copy of the hash it
136 points to.  You can ask the object for a copy with the I<hash> method.
137
138 =cut
139
140 # the new method can be inherited from FS::Record, if a table method is defined
141
142 sub table { 'cust_pay_pending'; }
143
144 =item insert
145
146 Adds this record to the database.  If there is an error, returns the error,
147 otherwise returns false.
148
149 =cut
150
151 # the insert method can be inherited from FS::Record
152
153 =item delete
154
155 Delete this record from the database.
156
157 =cut
158
159 # the delete method can be inherited from FS::Record
160
161 =item replace OLD_RECORD
162
163 Replaces the OLD_RECORD with this one in the database.  If there is an error,
164 returns the error, otherwise returns false.
165
166 =cut
167
168 # the replace method can be inherited from FS::Record
169
170 =item check
171
172 Checks all fields to make sure this is a valid pending payment.  If there is
173 an error, returns the error, otherwise returns false.  Called by the insert
174 and replace methods.
175
176 =cut
177
178 # the check method should currently be supplied - FS::Record contains some
179 # data checking routines
180
181 sub check {
182   my $self = shift;
183
184   my $error = 
185     $self->ut_numbern('paypendingnum')
186     || $self->ut_foreign_key('custnum', 'cust_main', 'custnum')
187     || $self->ut_money('paid')
188     || $self->ut_numbern('_date')
189     || $self->ut_textn('payunique')
190     || $self->ut_text('status')
191     #|| $self->ut_textn('statustext')
192     || $self->ut_anything('statustext')
193     #|| $self->ut_money('cust_balance')
194     || $self->ut_foreign_keyn('paynum', 'cust_pay', 'paynum' )
195     || $self->payinfo_check() #payby/payinfo/paymask/paydate
196   ;
197   return $error if $error;
198
199   $self->_date(time) unless $self->_date;
200
201   # UNIQUE index should catch this too, without race conditions, but this
202   # should give a better error message the other 99.9% of the time...
203   if ( length($self->payunique) ) {
204     my $cust_pay_pending = qsearchs('cust_pay_pending', {
205       'payunique'     => $self->payunique,
206       'paypendingnum' => { op=>'!=', value=>$self->paypendingnum },
207     });
208     if ( $cust_pay_pending ) {
209       #well, it *could* be a better error message
210       return "duplicate transaction - a payment with unique identifer ".
211              $self->payunique. " already exists";
212     }
213   }
214
215   $self->SUPER::check;
216 }
217
218 =back
219
220 =head1 BUGS
221
222 =head1 SEE ALSO
223
224 L<FS::Record>, schema.html from the base documentation.
225
226 =cut
227
228 1;
229