add skip_dcontext_suffix to skip CDRs with dcontext ending in a definable string...
[freeside.git] / FS / FS / payby.pm
1 package FS::payby;
2
3 use strict;
4 use vars qw(%hash %payby2bop);
5 use Tie::IxHash;
6 use Business::CreditCard;
7
8 =head1 NAME
9
10 FS::payby - Object methods for payment type records
11
12 =head1 SYNOPSIS
13
14   use FS::payby;
15
16   #for now...
17
18   my @payby = FS::payby->payby;
19
20   my $bool = FS::payby->can_payby('cust_main', 'CARD');
21
22   tie my %payby, 'Tie::IxHash', FS::payby->payby2longname
23
24   my @cust_payby = FS::payby->cust_payby;
25
26   tie my %payby, 'Tie::IxHash', FS::payby->cust_payby2longname
27
28 =head1 DESCRIPTION
29
30 Payment types.
31
32 =head1 METHODS
33
34 =over 4 
35
36 =item
37
38 =cut
39
40 # paybys can be any/all of:
41 # - a customer saved payment type (cust_payby.payby)
42 # - a payment or refund type (cust_pay.payby, cust_pay_batch.payby, cust_refund.payby)
43
44 # customer methods that start with 'D' will be interpreted as on-demand
45
46 tie %hash, 'Tie::IxHash',
47   'CARD' => {
48     tinyname  => 'card',
49     shortname => 'Credit card',
50     longname  => 'Credit card (automatic)',
51     realtime  => 1,
52   },
53   'DCRD' => {
54     tinyname  => 'card',
55     shortname => 'Credit card',
56     longname  => 'Credit card (on-demand)',
57     cust_pay  => 'CARD', #this is a customer type only, payments are CARD...
58     realtime  => 1,
59   },
60   'CHEK' => {
61     tinyname  => 'check',
62     shortname => 'Electronic check',
63     longname  => 'Electronic check (automatic)',
64     realtime  => 1,
65   },
66   'DCHK' => {
67     tinyname  => 'check',
68     shortname => 'Electronic check',
69     longname  => 'Electronic check (on-demand)',
70     cust_pay  => 'CHEK', #this is a customer type only, payments are CHEK...
71     realtime  => 1,
72   },
73   'BILL' => {
74     tinyname  => 'billing',
75     shortname => 'Billing',
76     payname   => 'Check',
77     longname  => 'Billing',
78     cust_main => '', #no longer a customer type
79   },
80   'PPAL' => {
81     tinyname  => 'PayPal',
82     shortname => 'PayPal',
83     longname  => 'PayPal',
84     cust_main => '', #not yet a customer type, but could be once we can do
85                      # invoice presentment via paypal
86   },
87   'PREP' => {
88     tinyname  => 'prepaid card',
89     shortname => 'Prepaid card',
90     longname  => 'Prepaid card',
91     cust_main => '', #this is a payment type only
92   },
93   'CASH' => {
94     tinyname  => 'cash',
95     shortname => 'Cash', # initial payment, then billing
96     longname  => 'Cash',
97     cust_main => '', #this is a payment type only
98   },
99   'WEST' => {
100     tinyname  => 'western union',
101     shortname => 'Western Union', # initial payment, then billing
102     longname  => 'Western Union',
103     cust_main => '', #this is a payment type only
104   },
105   'IDTP' => {
106     tinyname  => 'IDT',
107     shortname => 'IDT Payment Services',
108     longname  => 'IDT Payment Services',
109     cust_main => '', #this is a payment type only
110   },
111   'MCRD' => { #not the same as DCRD
112     tinyname  => 'card',
113     shortname => 'Manual credit card', # initial payment, then billing
114     longname  => 'Manual credit card', 
115     cust_main => '', #this is a payment type only
116   },
117   'MCHK' => { #not the same as DCHK
118     tinyname  => 'card',
119     shortname => 'Manual electronic check', # initial payment, then billing
120     longname  => 'Manual electronic check', 
121     cust_main => '', #this is a payment type only
122   },
123   'APPL' => {
124     tinyname  => 'apple store',
125     shortname => 'Apple Store',
126     longname  => 'Apple Store',
127     cust_main => '', #this is a payment type only
128   },
129   'ANRD' => {
130     tinyname  => 'android market',
131     shortname => 'Android Market',
132     longname  => 'Android Market',
133     cust_main => '', #this is a payment type only
134   },
135   'EDI' => {
136     tinyname  => 'EDI',
137     shortname => 'Electronic Debit (EDI)',
138     longname  => 'Electronic Debit (EDI)',
139     cust_main => '', #not a customer type
140   },
141   'WIRE' => {
142     tinyname  => 'Wire',
143     shortname => 'Wire transfer',
144     longname  => 'Wire transfer',
145     cust_main => '', #not a customer type
146   },
147   'CBAK' => {
148     tinyname  => 'chargeback',
149     shortname => 'Chargeback',
150     longname  => 'Chargeback',
151     cust_main => '', # not a customer type
152   },
153 ;
154
155 sub payby {
156   keys %hash;
157 }
158
159 sub can_payby {
160   my( $self, $table, $payby ) = @_;
161
162   #return "Illegal payby" unless $hash{$payby};
163   return 0 unless $hash{$payby};
164
165   $table = 'cust_pay' if $table =~ /^cust_(pay_pending|pay_batch|pay_void|refund)$/;
166   return 0 if exists( $hash{$payby}->{$table} );
167
168   return 1;
169 }
170
171 sub realtime {  # can use realtime payment facilities
172   my( $self, $payby ) = @_;
173
174   return 0 unless $hash{$payby};
175   return 0 unless exists( $hash{$payby}->{realtime} );
176
177   return $hash{$payby}->{realtime};
178 }
179
180 sub payby2shortname {
181   my $self = shift;
182   map { $_ => $hash{$_}->{shortname} } $self->payby;
183 }
184
185 sub payby2longname {
186   my $self = shift;
187   map { $_ => $hash{$_}->{longname} } $self->payby;
188 }
189
190 sub shortname {
191   my( $self, $payby ) = @_;
192   $hash{$payby}->{shortname};
193 }
194
195 sub payname {
196   my( $self, $payby ) = @_;
197   #$hash{$payby}->{payname} || $hash{$payby}->{shortname};
198   exists($hash{$payby}->{payname})
199     ? $hash{$payby}->{payname}
200     : $hash{$payby}->{shortname};
201 }
202
203 sub longname {
204   my( $self, $payby ) = @_;
205   $hash{$payby}->{longname};
206 }
207
208 %payby2bop = (
209   'CARD' => 'CC',
210   'CHEK' => 'ECHECK',
211   'MCRD' => 'CC', #?  but doesn't MCRD mean _offline_ card?  i think it got
212                   # overloaded for third-party card payments -- but no one is
213                   # doing those other than paypal now
214   'PPAL' => 'PAYPAL',
215 );
216
217 sub payby2bop {
218   my( $self, $payby ) = @_;
219   $payby2bop{ $self->payby2payment($payby) };
220 }
221
222 sub payby2payment {
223   my( $self, $payby ) = @_;
224   $hash{$payby}{'cust_pay'} || $payby;
225 }
226
227 sub cust_payby {
228   my $self = shift;
229   grep { ! exists $hash{$_}->{cust_main} } $self->payby;
230 }
231
232 sub cust_payby2shortname {
233   my $self = shift;
234   map { $_ => $hash{$_}->{shortname} } $self->cust_payby;
235 }
236
237 sub cust_payby2longname {
238   my $self = shift;
239   map { $_ => $hash{$_}->{longname} } $self->cust_payby;
240 }
241
242 =item payment_payby
243
244 Returns all values of payby that can be used by payments.
245
246 =cut
247
248 sub payment_payby {
249   my $self = shift;
250   grep { ! exists $hash{$_}->{cust_pay} } $self->payby;
251 }
252
253 =item payment_payby2longname
254
255 Returns hash, keys are L</payment_payby> types, values are payby longname.
256
257 =cut
258
259 sub payment_payby2longname {
260   my $self = shift;
261   map { $_ => $hash{$_}->{longname} } $self->payment_payby;
262 }
263
264 =item payment_payby2payname
265
266 Returns hash, keys are L</payment_payby> types, values are payby payname.
267
268 =cut
269
270 sub payment_payby2payname {
271   my $self = shift;
272   map { $_ => $self->payname($_) } $self->payment_payby;
273 }
274
275 =back
276
277 =head1 BUGS
278
279 This should eventually be an actual database table, and all tables that
280 currently have a char payby field should have a foreign key into here instead.
281
282 =head1 SEE ALSO
283
284 =cut
285
286 1;
287