import torrus 1.0.9
[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}).{3}(.).{11}(.{19}).{6}(.{30}).{17}(.{9})(.{18}).{6}(.{14}).{23}(.).{9}\r?$',
18   'fields' => [ qw(
19     recordtype
20     batchnum
21     subtype
22     paybatchnum
23     custname
24     bank
25     payinfo
26     paid
27     status
28     ) ],
29   'hook' => sub {
30       my $hash = shift;
31       $hash->{'paid'} = sprintf("%.2f", $hash->{'paid'} / 100 );
32       $hash->{'_date'} = time;
33       $hash->{'payinfo'} =~ s/^(\S+).*/$1/; # these often have trailing spaces
34       $hash->{'payinfo'} = $hash->{'payinfo'} . '@' . $hash->{'bank'};
35   },
36   'approved'    => sub { 
37       my $hash = shift;
38       $hash->{'status'} eq ' '
39   },
40   'declined'    => sub {
41       my $hash = shift;
42       grep { $hash->{'status'} eq $_ } ('E', 'R', 'U', 'T');
43   },
44   'begin_condition' => sub {
45       my $hash = shift;
46       $hash->{recordtype} eq '1'; # Detail Record
47   },
48   'end_hook'    => sub {
49       my( $hash, $total, $line ) = @_;
50       $total = sprintf("%.2f", $total);
51       # We assume here that this is an 'All Records' or 'Input Records'
52       # report.
53       my $batch_total = sprintf("%.2f", substr($line, 59, 18) / 100);
54       return "Our total $total does not match bank total $batch_total!"
55         if $total != $batch_total;
56       '';
57   },
58   'end_condition' => sub {
59       my $hash = shift;
60       $hash->{recordtype} eq '4'; # Client Trailer Record
61   },
62   'skip_condition' => sub {
63       my $hash = shift;
64       $hash->{'subtype'} ne '0';
65   },
66 );
67
68 %export_info = (
69   init => sub {
70     $conf = shift;
71     ($client_num,
72      $shortname,
73      $longname,
74      $trans_code, 
75      ) = $conf->config("batchconfig-RBC");
76     $i = 1;
77   },
78   header => sub { 
79     my $pay_batch = shift;
80     '$$AAPASTD0152[PROD[NL$$'."\n".
81     '000001'.
82     'A'.
83     'HDR'.
84     sprintf("%10s", $client_num).
85     sprintf("%-30s", $longname).
86     sprintf("%04u", $pay_batch->batchnum).
87     time2str("%Y%j", $pay_batch->download).
88     'CAD'.
89     '1'.
90     ' ' x 87  # filler/reserved fields
91     ;
92   },
93   row => sub {
94     my ($cust_pay_batch, $pay_batch) = @_;
95     my ($account, $aba) = split('@', $cust_pay_batch->payinfo);
96     $i++;
97     sprintf("%06u", $i).
98     'D'.
99     sprintf("%3s",$trans_code).
100     sprintf("%10s",$client_num).
101     ' '.
102     sprintf("%-19s", $cust_pay_batch->paybatchnum).
103     '00'.
104     sprintf("%09u", $aba).
105     sprintf("%-18s", $account).
106     ' '.
107     sprintf("%010.0f",$cust_pay_batch->amount*100).
108     '      '.
109     time2str("%Y%j", $pay_batch->download).
110     sprintf("%-30s", $cust_pay_batch->cust_main->first . ' ' .
111                      $cust_pay_batch->cust_main->last).
112     'E'. # English
113     ' '.
114     sprintf("%-15s", $shortname).
115     'CAD'.
116     ' '.
117     'CAN'.
118     '    '.
119     'N' # no customer optional information follows
120     ;
121 # Note: IAT Address Information and Remittance records are not 
122 # supported. This means you probably can't process payments 
123 # destined to U.S. bank accounts.  If you need this feature, contact 
124 # Freeside Internet Services.
125   },
126   footer => sub {
127     my ($pay_batch, $batchcount, $batchtotal) = @_;
128     sprintf("%06u", $i + 1).
129     'Z'.
130     'TRL'.
131     sprintf("%10s", $client_num).
132     ' ' x 20 .
133     sprintf("%06u", $batchcount).
134     sprintf("%014.0f", $batchtotal*100).
135     '00' .
136     '000000' . # total number of customer information records
137     ' ' x 84
138     ;
139   },
140 );
141
142 1;
143