handle census tract properly in location upgrade, #23422
[freeside.git] / FS / FS / Cron / pay_batch.pm
1 package FS::Cron::pay_batch;
2
3 use strict;
4 use vars qw( @ISA @EXPORT_OK $me $DEBUG );
5 use Exporter;
6 use Date::Format;
7 use FS::UID qw(dbh);
8 use FS::Record qw( qsearch qsearchs );
9 use FS::Conf;
10 use FS::queue;
11 use FS::agent;
12
13 @ISA = qw( Exporter );
14 @EXPORT_OK = qw ( batch_submit batch_receive );
15 $DEBUG = 0;
16 $me = '[FS::Cron::pay_batch]';
17
18 #freeside-daily %opt:
19 #  -v: enable debugging
20 #  -l: debugging level
21 #  -m: Experimental multi-process mode uses the job queue for multi-process and/or multi-machine billing.
22 #  -r: Multi-process mode dry run option
23 #  -a: Only process customers with the specified agentnum
24
25 sub batch_submit {
26   my %opt = @_;
27   local $DEBUG = ($opt{l} || 1) if $opt{v};
28   # if anything goes wrong, don't try to roll back previously submitted batches
29   local $FS::UID::AutoCommit = 1;
30   
31   my $dbh = dbh;
32
33   warn "$me batch_submit\n" if $DEBUG;
34   my $conf = FS::Conf->new;
35
36   # need to respect -a somehow, but for now none of this is per-agent
37   if ( $opt{a} ) {
38     warn "Payment batch processing skipped in per-agent mode.\n" if $DEBUG;
39     return;
40   }
41   my %gateways;
42   foreach my $payby ('CARD', 'CHEK') {
43     my $gatewaynum = $conf->config("batch-gateway-$payby");
44     next if !$gatewaynum;
45     my $gateway = FS::payment_gateway->by_key($gatewaynum)
46       or die "payment_gateway '$gatewaynum' not found\n";
47
48     if ( $gateway->batch_processor->can('default_transport') ) {
49
50       foreach my $pay_batch ( 
51         qsearch('pay_batch', { status => 'O', payby => $payby }) 
52       ) {
53
54         warn "Exporting batch ".$pay_batch->batchnum."\n" if $DEBUG;
55         eval { $pay_batch->export_to_gateway( $gateway, debug => $DEBUG ); };
56
57         if ( $@ ) {
58           # warn the error and continue. rolling back the transaction once 
59           # we've started sending batches is bad.
60           warn "error submitting batch ".$pay_batch->batchnum." to gateway '".
61           $gateway->label."\n$@\n";
62         }
63       }
64
65     } else { #can't(default_transport)
66       warn "Payment gateway '".$gateway->label.
67       "' doesn't support automatic transport; skipped.\n";
68     }
69   } #$payby
70
71   1;
72 }
73
74 sub batch_receive {
75   my %opt = @_;
76   local $DEBUG = ($opt{l} || 1) if $opt{v};
77   local $FS::UID::AutoCommit = 0;
78
79   my $dbh = dbh;
80   my $error;
81
82   warn "$me batch_receive\n" if $DEBUG;
83   my $conf = FS::Conf->new;
84
85   # need to respect -a somehow, but for now none of this is per-agent
86   if ( $opt{a} ) {
87     warn "Payment batch processing skipped in per-agent mode.\n" if $DEBUG;
88     return;
89   }
90   my %gateways;
91   foreach my $payby ('CARD', 'CHEK') {
92     my $gatewaynum = $conf->config("batch-gateway-$payby");
93     next if !$gatewaynum;
94     # If the same gateway is selected for both paybys, only import it once
95     $gateways{$gatewaynum} = FS::payment_gateway->by_key($gatewaynum);
96     if ( !$gateways{$gatewaynum} ) {
97       $dbh->rollback;
98       die "batch-gateway-$payby gateway $gatewaynum not found\n";
99     }
100   }
101
102   foreach my $gateway (values %gateways) {
103     if ( $gateway->batch_processor->can('default_transport') ) {
104       warn "Importing results from '".$gateway->label."'\n" if $DEBUG;
105       $error = eval { 
106         FS::pay_batch->import_from_gateway( gateway =>$gateway, debug => $DEBUG ) 
107       } || $@;
108       if ( $error ) {
109         # this we can roll back
110         $dbh->rollback;
111         die "error receiving from gateway '".$gateway->label."':\n$error\n";
112       }
113     } 
114     # else we already warned about it above
115   } #$gateway
116
117   # resolve batches if we can
118   foreach my $pay_batch (qsearch('pay_batch', { status => 'I' })) {
119     warn "Trying to resolve batch ".$pay_batch->batchnum."\n" if $DEBUG;
120     $error = $pay_batch->try_to_resolve;
121     if ( $error ) {
122       $dbh->rollback;
123       die "unable to resolve batch ".$pay_batch->batchnum.":\n$error\n";
124     }
125   }
126
127   $dbh->commit;
128 }
129 1;