33a725e22da8383729c8c5f28849a033a3d3e0d8
[freeside.git] / FS / FS / pay_batch / RBC.pm
1 package FS::pay_batch::RBC;
2
3 use strict;
4 use vars qw(@ISA %import_info %export_info $name);
5 use Date::Format 'time2str';
6 use FS::Conf;
7
8 my $conf;
9 my ($client_num, $shortname, $longname, $trans_code, $i);
10
11 $name = 'RBC';
12 # Royal Bank of Canada ACH Direct Payments Service
13
14 %import_info = (
15   'filetype'    => 'fixed',
16   'formatre'    => 
17   '^(.).{18}(.{4}).{15}(.{19}).{6}(.{30}).{17}(.{9})(.{18}).{6}(.{14}).{23}(.).{9}$',
18   'fields' => [ qw(
19     recordtype
20     batchnum
21     paybatchnum
22     custname
23     bank
24     payinfo
25     paid
26     status
27     ) ],
28   'hook' => sub {
29       my $hash = shift;
30       $hash->{'paid'} = sprintf("%.df", $hash->{'paid'} / 100 );
31       $hash->{'_date'} = time;
32       $hash->{'payinfo'} = $hash->{'payinfo'} . '@' . $hash->{'bank'};
33   },
34   'approved'    => sub { 
35       my $hash = shift;
36       $hash->{'status'} eq ' '
37   },
38   'declined'    => sub {
39       my $hash = shift;
40       grep { $hash->{'status'} eq $_ } ('E', 'R', 'U', 'T');
41   },
42   'end_hook'    => sub {
43       my( $hash, $total, $line ) = @_;
44       $total = sprintf("%.2f", $total);
45       my $batch_total = sprintf("%.2f", substr($line, 140, 18) / 100);
46       return "Our total $total does not match bank total $batch_total!"
47         if $total != $batch_total;
48       '';
49   },
50   'end_condition' => sub {
51       my $hash = shift;
52       $hash->{recordtype} == '3'; # Account Trailer Record
53   },
54 );
55
56 %export_info = (
57   init => sub {
58     $conf = shift;
59     ($client_num,
60      $shortname,
61      $longname,
62      $trans_code, 
63      ) = $conf->config("batchconfig-RBC");
64     $i = 1;
65   },
66   header => sub { 
67     my $pay_batch = shift;
68     '$$AAPASTD0152[PROD[NL$$'."\n".
69     '000001'.
70     'A'.
71     'HDR'.
72     sprintf("%10s", $client_num).
73     sprintf("%-30s", $longname).
74     sprintf("%04u", $pay_batch->batchnum).
75     time2str("%Y%j", $pay_batch->download).
76     'CAD'.
77     '1'.
78     ' ' x 87  # filler/reserved fields
79     ;
80   },
81   row => sub {
82     my ($cust_pay_batch, $pay_batch) = @_;
83     my ($account, $aba) = split('@', $cust_pay_batch->payinfo);
84     $i++;
85     sprintf("%06u", $i).
86     'D'.
87     sprintf("%3s",$trans_code).
88     sprintf("%10s",$client_num).
89     ' '.
90     sprintf("%-19s", $cust_pay_batch->paybatchnum).
91     '00'.
92     sprintf("%09u", $aba).
93     sprintf("%-18s", $account).
94     ' '.
95     sprintf("%010u",$cust_pay_batch->amount*100).
96     '      '.
97     time2str("%Y%j", $pay_batch->download).
98     sprintf("%-30s", $cust_pay_batch->cust_main->first . ' ' .
99                      $cust_pay_batch->cust_main->last).
100     'E'. # English
101     ' '.
102     sprintf("%-15s", $shortname).
103     'CAD'.
104     ' '.
105     'CAN'.
106     '    '.
107     'N' # no customer optional information follows
108     ;
109 # Note: IAT Address Information and Remittance records are not 
110 # supported. This means you probably can't process payments 
111 # destined to U.S. bank accounts.  If you need this feature, contact 
112 # Freeside Internet Services.
113   },
114   footer => sub {
115     my ($pay_batch, $batchcount, $batchtotal) = @_;
116     sprintf("%06u", $i + 1).
117     'Z'.
118     'TRL'.
119     sprintf("%10s", $client_num).
120     ' ' x 20 .
121     sprintf("%06u", $batchcount).
122     sprintf("%014u", $batchtotal*100).
123     '00' .
124     '000000' . # total number of customer information records
125     ' ' x 84
126     ;
127   },
128 );
129
130 1;
131