X-Git-Url: http://git.freeside.biz/gitweb/?p=freeside.git;a=blobdiff_plain;f=FS%2FFS%2Fpay_batch%2Ftd_eft1464.pm;h=e16b0ee39e114550760ec44e947bbf28e39ef64b;hp=1fbf2ade2d9784918aee31f5fbc4c76e2d31ecf2;hb=8a16e8aa94e23ad44c0d4d9713ca009913f15b5b;hpb=5188e8406a1fa2bee63ea81090ffefe3d4bf1b89 diff --git a/FS/FS/pay_batch/td_eft1464.pm b/FS/FS/pay_batch/td_eft1464.pm index 1fbf2ade2..e16b0ee39 100644 --- a/FS/FS/pay_batch/td_eft1464.pm +++ b/FS/FS/pay_batch/td_eft1464.pm @@ -48,87 +48,13 @@ my $i; $name = 'td_eft1464'; # TD Bank EFT 1464 Byte format +# https://www.payments.ca/sites/default/files/standard-005.pdf -%import_info = ( - 'filetype' => 'variable', - 'parse' => \&parse, - 'fields' => [ qw( - status - paid - paybatchnum - ) ], - 'hook' => sub { - my $hash = shift; - $hash->{'_date'} = time; - $hash->{'paid'} = sprintf('%.2f', $hash->{'paid'}); - }, - 'approved' => sub { - my $hash = shift; - $hash->{'status'} eq 'A' - }, - 'declined' => sub { - my $hash = shift; - $hash->{'status'} eq 'D'; - }, - 'begin_condition' => sub { - my $hash = shift; - $hash->{'status'} eq 'A' or $hash->{'status'} eq 'D'; - }, - 'end_condition' => sub { - my $hash = shift; - $hash->{'status'} eq 'END' - }, - 'close_condition' => sub { - my $batch = shift; - my @cust_pay_batch = qsearch('cust_pay_batch', - { batchnum => $batch->batchnum } - ); - return ( (grep {! length($_->status) } @cust_pay_batch) == 0 ); - }, -); - -sub parse { - my ($batch, $line) = @_; - $batch->setfield('import_state','') if !$batch->import_state; - return 'END' if $batch->import_state eq 'END'; - if( $batch->import_state eq '212' ) { - # APX212 fields: - # trace number, trans type, amount, due date, routing number, - # account number, xref number, return routing number and account - # The only ones we take are amount and xref number. - if( $line =~ /CREDITS\s+DEBITS/ ) { - $batch->setfield('import_state', 'END'); - return 'END'; - } - $line =~ /^\d{22} D\d{3} (.{14}) \d{5} \d{4}-\d{5} .{12} (.{19}).*$/ - or die "can't parse: $line"; - # strip leading zeroes/spaces from paybatchnum at this point - return ('A', $1, sprintf('%u',$2)); - } - elsif( $batch->import_state eq '234' ) { - # APX234 fields: - # payor name, xref number, due date, routing number, account number, - # amount, reason for return - if( $line =~ /TOTAL NUMBER -/ ) { - $batch->setfield('import_state', 'END'); - return 'END'; - } - $line =~ /^.{22} (.{19}) \d\d\/\d\d\/\d\d \d{9} .{12} (.{14}).*$/ - or die "can't parse: $line"; - return ('D', $2, sprintf('%u',$1)); - } - else { - if ( $line =~ /ITEM TRACE NUMBER/ ) { - $batch->setfield('import_state','212'); - } - elsif ( $line =~ /REASON FOR RETURN/ ) { - $batch->setfield('import_state','234'); - } # else leave it undefined - return 'HEADER'; - } -} +%import_info = ( filetype => 'NONE' ); +# just to suppress warning; importing this format is a fatal error %export_info = ( + delimiter => '', init => sub { $conf = shift; @opt{ @@ -140,11 +66,11 @@ sub parse { 'retacct', 'cpacode', } = $conf->config("batchconfig-td_eft1464"); - $opt{'origid'} = sprintf('%-10s', $opt{'origid'}); - $opt{'shortname'} = sprintf('%-15s', $opt{'shortname'}); - $opt{'longname'} = sprintf('%-30s', $opt{'longname'}); - $opt{'retbranch'} = '0004'.sprintf('%5s',$opt{'retbranch'}); - $opt{'retacct'} = sprintf('%-11s', $opt{'retacct'}). ' '; + $opt{'origid'} = sprintf('%-10.10s', $opt{'origid'}); + $opt{'shortname'} = sprintf('%-15.15s', $opt{'shortname'}); + $opt{'longname'} = sprintf('%-30.30s', $opt{'longname'}); + $opt{'retbranch'} = '0004'.sprintf('%5.5s',$opt{'retbranch'}); + $opt{'retacct'} = sprintf('%-11.11s', $opt{'retacct'}). ' '; $i = 1; }, header => sub { @@ -152,13 +78,13 @@ sub parse { my @cust_pay_batch = @{(shift)}; my $time = $pay_batch->download || time; my $now = sprintf("%03u%03u", - (localtime(time))[5],#year since 1900 + (localtime(time))[5] % 100,#year since 1900 (localtime(time))[7]+1);#day of year # Request settlement the next day my $duedate = time+86400; $opt{'due'} = sprintf("%03u%03u", - (localtime($duedate))[5], + (localtime($duedate))[5] % 100, (localtime($duedate))[7]+1); $opt{'fcn'} = @@ -170,17 +96,25 @@ sub parse { $opt{'fcn'}, $now, $opt{'datacenter'}, - ' ' x 1429 #filler + ' ' x 1429, #filler ); }, row => sub { my ($cust_pay_batch, $pay_batch) = @_; my ($account, $aba) = split('@', $cust_pay_batch->payinfo); + if ( $aba =~ /^(\d+)\.(\d+)$/ ) { #branch.route + $aba = $2.$1; #routebranch + } $i++; # The 1464 byte format supports up to 5 payments per line, # but we're only going to send 1. + + ## set to D for debit by default, then override to what cust_pay_batch has as payments may not have paycode. + my $debitorcredit = 'D'; + $debitorcredit = $cust_pay_batch->paycode unless !$cust_pay_batch->paycode; + my $control = join('', - 'D', # for 'debit' + $debitorcredit, # D for 'debit' or C for Credit sprintf("%09u", $i), #record number $opt{'origid'}, $opt{'fcn'}, @@ -190,40 +124,59 @@ sub parse { sprintf('%010.0f', $cust_pay_batch->amount*100), $opt{'due'}, #due date...? XXX sprintf('%09u', $aba), - sprintf('%-12s', $account), - ' ' x 22, - ' ' x 3, + sprintf('%-12.12s', $account), + '0' x 22, + '0' x 3, $opt{'shortname'}, - sprintf('%-30s', + sprintf('%-30.30s', join(' ', $cust_pay_batch->first, $cust_pay_batch->last) ), $opt{'longname'}, $opt{'origid'}, - sprintf('%-19s', $cust_pay_batch->paybatchnum), # originator reference num + sprintf('%-19.19s', $cust_pay_batch->paybatchnum), # originator reference num $opt{'retbranch'}, $opt{'retacct'}, + ' ' x 15, ' ' x 22, ' ' x 2, '0' x 11, ); - return $control . $payment . (' ' x 720); + return sprintf('%-1464s',$control . $payment) ; }, footer => sub { my ($pay_batch, $batchcount, $batchtotal) = @_; + my $totaldebittxns = $pay_batch->type eq "DEBIT" ? $batchtotal*100 : 0; + my $countdebittxns = $pay_batch->type eq "DEBIT" ? $batchcount : 0; + my $totalcredittxns = $pay_batch->type eq "CREDIT" ? $batchtotal*100 : 0; + my $countcredittxns = $pay_batch->type eq "CREDIT" ? $batchcount : 0; join('', 'Z', sprintf('%09u', $batchcount + 2), $opt{'origid'}, $opt{'fcn'}, - sprintf('%014.0f', $batchtotal*100), # total of debit txns - sprintf('%08u', $batchcount), # number of debit txns - '0' x 14, # total of credit txns - '0' x 8, # total of credit txns + sprintf('%014.0f', $totaldebittxns), # total of debit txns + sprintf('%08u', $countdebittxns), # number of debit txns + sprintf('%014.0f', $totalcredittxns), # total of debit txns + sprintf('%08u', $countcredittxns), # number of debit txns ' ' x 1396, ) }, ); +## this format can handle credit transactions +sub can_handle_credits { + 1; +} + +sub _upgrade_gateway { + my $conf = FS::Conf->new; + my @batchconfig = $conf->config('batchconfig-td_eft1464'); + my %options; + @options{ qw(originator datacentre short_name long_name return_branch + return_account cpa_code) } = @batchconfig; + ( 'TD_EFT', %options ); +} + 1;