From 6c375156081be5d2023001ed8eaac9b6db568e95 Mon Sep 17 00:00:00 2001 From: jeff Date: Wed, 9 Aug 2006 06:43:02 +0000 Subject: [PATCH] batch refactor --- FS/FS/Schema.pm | 8 +- FS/FS/Setup.pm | 7 ++ FS/FS/cust_bill.pm | 25 ++++- FS/FS/cust_main.pm | 30 ++++- FS/FS/cust_pay_batch.pm | 207 ++++++++++++++++++++++++++++++----- FS/FS/part_bill_event.pm | 2 +- FS/FS/pay_batch.pm | 8 +- FS/FS/payby.pm | 5 + README.1.7.0 | 2 + httemplate/browse/cust_pay_batch.cgi | 33 ++++-- httemplate/browse/pay_batch.cgi | 54 +++++++++ httemplate/docs/schema.html | 4 + httemplate/misc/download-batch.cgi | 37 ++++++- 13 files changed, 370 insertions(+), 52 deletions(-) create mode 100755 httemplate/browse/pay_batch.cgi diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm index 04dcb8245..5dac26600 100644 --- a/FS/FS/Schema.pm +++ b/FS/FS/Schema.pm @@ -542,7 +542,9 @@ sub tables_hashref { 'pay_batch' => { #batches of payments to an external processor 'columns' => [ 'batchnum', 'serial', '', '', '', '', - 'status', 'char', 'NULL', 1, '', '', + 'status', 'char', 'NULL', 1, '', '', + 'download', @date_type, 'NULL', '', + 'upload', @date_type, 'NULL', '', ], 'primary_key' => 'batchnum', 'unique' => [], @@ -565,11 +567,13 @@ sub tables_hashref { 'zip', 'varchar', 'NULL', 10, '', '', 'country', 'char', '', 2, '', '', # 'trancode', 'int', '', '', '', '' + 'payby', 'char', '', 4, '', '', # CARD/BILL/COMP, should be 'payinfo', 'varchar', '', 512, '', '', #'exp', @date_type, '', '' - 'exp', 'varchar', '', 11, '', '', + 'exp', 'varchar', 'NULL', 11, '', '', 'payname', 'varchar', 'NULL', $char_d, '', '', 'amount', @money_type, '', '', + 'status', 'varchar', 'NULL', $char_d, '', '', ], 'primary_key' => 'paybatchnum', 'unique' => [], diff --git a/FS/FS/Setup.pm b/FS/FS/Setup.pm index 7475d3782..90f6f1011 100644 --- a/FS/FS/Setup.pm +++ b/FS/FS/Setup.pm @@ -168,6 +168,13 @@ sub initial_data { 'weight' => 50, 'plan' => 'send', }, + { 'payby' => 'DCLN', + 'event' => 'Suspend', + 'seconds' => 0, + 'eventcode' => '$cust_bill->suspend();', + 'weight' => 40, + 'plan' => 'suspend', + }, ], #you must create a service definition. An example of a service definition diff --git a/FS/FS/cust_bill.pm b/FS/FS/cust_bill.pm index def84f91a..d45b66faf 100644 --- a/FS/FS/cust_bill.pm +++ b/FS/FS/cust_bill.pm @@ -1284,6 +1284,9 @@ sub batch_card { my $self = shift; my $cust_main = $self->cust_main; + my $amount = sprintf("%.2f", $cust_main->balance - $cust_main->in_transit_payments); + return '' unless $amount > 0; + my $oldAutoCommit = $FS::UID::AutoCommit; local $FS::UID::AutoCommit = 0; my $dbh = dbh; @@ -1300,9 +1303,14 @@ sub batch_card { } } + my $old_cust_pay_batch = qsearchs('cust_pay_batch', { + 'batchnum' => $pay_batch->getfield('batchnum'), + 'custnum' => $cust_main->getfield('custnum'), + } ); + my $cust_pay_batch = new FS::cust_pay_batch ( { 'batchnum' => $pay_batch->getfield('batchnum'), - 'invnum' => $self->getfield('invnum'), + 'invnum' => $self->getfield('invnum'), # is there a better value? 'custnum' => $cust_main->getfield('custnum'), 'last' => $cust_main->getfield('last'), 'first' => $cust_main->getfield('first'), @@ -1312,12 +1320,23 @@ sub batch_card { 'state' => $cust_main->getfield('state'), 'zip' => $cust_main->getfield('zip'), 'country' => $cust_main->getfield('country'), + 'payby' => $cust_main->payby, 'payinfo' => $cust_main->payinfo, 'exp' => $cust_main->getfield('paydate'), 'payname' => $cust_main->getfield('payname'), - 'amount' => $self->owed, + 'amount' => $amount, # consolidating } ); - my $error = $cust_pay_batch->insert; + + $cust_pay_batch->paybatchnum($old_cust_pay_batch->paybatchnum) + if $old_cust_pay_batch; + + my $error; + if ($old_cust_pay_batch) { + $error = $cust_pay_batch->replace($old_cust_pay_batch) + } else { + $error = $cust_pay_batch->insert; + } + if ( $error ) { $dbh->rollback if $oldAutoCommit; die $error; diff --git a/FS/FS/cust_main.pm b/FS/FS/cust_main.pm index f4568a8a0..f1d969cd1 100644 --- a/FS/FS/cust_main.pm +++ b/FS/FS/cust_main.pm @@ -2046,6 +2046,8 @@ quiet - set true to surpress email card/ACH decline notices. freq - "1d" for the traditional, daily events (the default), or "1m" for the new monthly events +payby - allows for one time override of normal customer billing method + =cut sub collect { @@ -2116,7 +2118,10 @@ sub collect { } qsearch( { 'table' => 'part_bill_event', - 'hashref' => { 'payby' => $self->payby, + 'hashref' => { 'payby' => (exists($options{'payby'}) + ? $options{'payby'} + : $self->payby + ), 'disabled' => '', }, 'extra_sql' => $extra_sql, } ) @@ -3143,6 +3148,29 @@ sub balance_date { ); } +=item in_transit_payments + +Returns the total of requests for payments for this customer pending in +batches in transit to the bank. See L and L + +=cut + +sub in_transit_payments { + my $self = shift; + my $in_transit_payments = 0; + foreach my $pay_batch ( qsearch('pay_batch', { + 'status' => 'I', + } ) ) { + foreach my $cust_pay_batch ( qsearch('cust_pay_batch', { + 'batchnum' => $pay_batch->batchnum, + 'custnum' => $self->custnum, + } ) ) { + $in_transit_payments += $cust_pay_batch->amount; + } + } + sprintf( "%.2f", $in_transit_payments ); +} + =item paydate_monthyear Returns a two-element list consisting of the month and year of this customer's diff --git a/FS/FS/cust_pay_batch.pm b/FS/FS/cust_pay_batch.pm index 117d72561..e057334c2 100644 --- a/FS/FS/cust_pay_batch.pm +++ b/FS/FS/cust_pay_batch.pm @@ -1,12 +1,17 @@ package FS::cust_pay_batch; use strict; -use vars qw( @ISA ); -use FS::Record qw(dbh qsearchs); +use vars qw( @ISA $DEBUG ); +use FS::Record qw(dbh qsearch qsearchs); use Business::CreditCard; @ISA = qw( FS::Record ); +# 1 is mostly method/subroutine entry and options +# 2 traces progress of some operations +# 3 is even more information including possibly sensitive data +$DEBUG = 0; + =head1 NAME FS::cust_pay_batch - Object methods for batch cards @@ -37,6 +42,10 @@ following fields are currently supported: =item paybatchnum - primary key (automatically assigned) +=item batchnum - indentifies group in batch + +=item payby - CARD/CHEK/LECB/BILL/COMP + =item payinfo =item exp - card expiration @@ -65,6 +74,8 @@ following fields are currently supported: =item country +=item status + =back =head1 METHODS @@ -94,16 +105,8 @@ otherwise returns false. =item replace OLD_RECORD -#inactive -# -#Replaces the OLD_RECORD with this one in the database. If there is an error, -#returns the error, otherwise returns false. - -=cut - -sub replace { - return "Can't (yet?) replace batched transactions!"; -} +Replaces the OLD_RECORD with this one in the database. If there is an error, +returns the error, otherwise returns false. =item check @@ -119,7 +122,6 @@ sub check { my $error = $self->ut_numbern('paybatchnum') || $self->ut_numbern('trancode') #depriciated - || $self->ut_number('payinfo') || $self->ut_money('amount') || $self->ut_number('invnum') || $self->ut_number('custnum') @@ -137,6 +139,10 @@ sub check { $self->first =~ /^([\w \,\.\-\']+)$/ or return "Illegal first name"; $self->first($1); + $self->payby =~ /^(CARD|CHEK|LECB|BILL|COMP|PREP|CASH|WEST|MCRD)$/ + or return "Illegal payby"; + $self->payby($1); + # FIXME # there is no point in false laziness here # we will effectively set "check_payinfo to 0" @@ -152,7 +158,8 @@ sub check { #return "Unknown card type" if cardtype($cardnum) eq "Unknown"; if ( $self->exp eq '' ) { - return "Expiration date required"; #unless + return "Expiration date required" + unless $self->payby =~ /^(CHEK|DCHK|LECB|WEST)$/; $self->exp(''); } else { if ( $self->exp =~ /^(\d{4})[\/\-](\d{1,2})[\/\-](\d{1,2})$/ ) { @@ -226,7 +233,11 @@ sub import_results { my $format = $param->{'format'}; my $paybatch = $param->{'paybatch'}; + my $filetype; # CSV, Fixed80, Fixed264 my @fields; + my $formatre; # for Fixed.+ + my @values; + my $begin_condition; my $end_condition; my $end_hook; my $hook; @@ -235,6 +246,8 @@ sub import_results { if ( $format eq 'csv-td_canada_trust-merchant_pc_batch' ) { + $filetype = "CSV"; + @fields = ( 'paybatchnum', # Reference#: Invoice number of the transaction 'paid', # Amount: Amount of the transaction. Dollars and cents @@ -293,6 +306,58 @@ sub import_results { }; + }elsif ( $format eq 'PAP' ) { + + $filetype = "Fixed264"; + + @fields = ( + 'recordtype', # We are interested in the 'D' or debit records + 'batchnum', # Record#: batch number we used when sending the file + 'datacenter', # Where in the bowels of the bank the data was processed + 'paid', # Amount: Amount of the transaction. Dollars and cents + # with no decimal entered. + '_date', # Transaction Date: Date the Transaction was processed + 'bank', # Routing information + 'payinfo', # Account number for the transaction + 'paybatchnum', # Reference#: Invoice number of the transaction + ); + + $formatre = '^(.).{19}(.{4})(.{3})(.{10})(.{6})(.{9})(.{12}).{110}(.{19}).{71}$'; + + $end_condition = sub { + my $hash = shift; + $hash->{'recordtype'} eq 'W'; + }; + + $end_hook = sub { + my( $hash, $total) = @_; + $total = sprintf("%.2f", $total); + my $batch_total = $hash->{'datacenter'}.$hash->{'paid'}. + substr($hash->{'_date'},0,1); # YUCK! + $batch_total = sprintf("%.2f", $batch_total / 100 ); + return "Our total $total does not match bank total $batch_total!" + if $total != $batch_total; + ''; + }; + + $hook = sub { + my $hash = shift; + $hash->{'paid'} = sprintf("%.2f", $hash->{'paid'} / 100 ); + my $tmpdate = timelocal( 0,0,1,1,0,substr($hash->{'_date'}, 0, 3)+2000); + $tmpdate += 86400*(substr($hash->{'_date'}, 3, 3)-1) ; + $hash->{'_date'} = $tmpdate; + $hash->{'payinfo'} = $hash->{'payinfo'} . '@' . $hash->{'bank'}; + }; + + $approved_condition = sub { + 1; + }; + + $declined_condition = sub { + 0; + }; + + } else { return "Unknown format $format"; } @@ -316,10 +381,10 @@ sub import_results { return "batch $paybatch is not in transit"; }; - my %batchhash = $pay_batch->hash; - $batchhash{'status'} = 'R'; # Resolved - my $newbatch = new FS::pay_batch ( \%batchhash ); - my $error = $newbatch->replace($paybatch); + my $newbatch = new FS::pay_batch { $pay_batch->hash }; + $newbatch->status('R'); # Resolved + $newbatch->upload(time); + my $error = $newbatch->replace($pay_batch); if ( $error ) { $dbh->rollback if $oldAutoCommit; return $error @@ -331,12 +396,23 @@ sub import_results { next if $line =~ /^\s*$/; #skip blank lines - $csv->parse($line) or do { + if ($filetype eq "CSV") { + $csv->parse($line) or do { + $dbh->rollback if $oldAutoCommit; + return "can't parse: ". $csv->error_input(); + }; + @values = $csv->fields(); + }elsif ($filetype eq "Fixed80" || $filetype eq "Fixed264"){ + @values = $line =~ /$formatre/; + unless (@values) { + $dbh->rollback if $oldAutoCommit; + return "can't parse: ". $line; + }; + }else{ $dbh->rollback if $oldAutoCommit; - return "can't parse: ". $csv->error_input(); - }; + return "Unknown file type $filetype"; + } - my @values = $csv->fields(); my %hash; foreach my $field ( @fields ) { my $value = shift @values; @@ -354,26 +430,25 @@ sub import_results { } my $cust_pay_batch = - qsearchs('cust_pay_batch', { 'paybatchnum' => $hash{'paybatchnum'} } ); + qsearchs('cust_pay_batch', { 'paybatchnum' => $hash{'paybatchnum'}+0 } ); unless ( $cust_pay_batch ) { $dbh->rollback if $oldAutoCommit; return "unknown paybatchnum $hash{'paybatchnum'}\n"; } my $custnum = $cust_pay_batch->custnum, + my $payby = $cust_pay_batch->payby, - my $error = $cust_pay_batch->delete; - if ( $error ) { - $dbh->rollback if $oldAutoCommit; - return "error removing paybatchnum $hash{'paybatchnum'}: $error\n"; - } + my $new_cust_pay_batch = new FS::cust_pay_batch { $cust_pay_batch->hash }; &{$hook}(\%hash); if ( &{$approved_condition}(\%hash) ) { + $new_cust_pay_batch->status('Approved'); + my $cust_pay = new FS::cust_pay ( { 'custnum' => $custnum, - 'payby' => 'CARD', + 'payby' => $payby, 'paybatch' => $paybatch, map { $_ => $hash{$_} } (qw( paid _date payinfo )), } ); @@ -388,11 +463,83 @@ sub import_results { } elsif ( &{$declined_condition}(\%hash) ) { + $new_cust_pay_batch->status('Declined'); + #this should be configurable... if anybody else ever uses batches - $cust_pay_batch->cust_main->suspend; + # $cust_pay_batch->cust_main->suspend; + + foreach my $part_bill_event ( + sort { $a->seconds <=> $b->seconds + || $a->weight <=> $b->weight + || $a->eventpart <=> $b->eventpart } + grep { ! qsearch( 'cust_bill_event', { + 'invnum' => $cust_pay_batch->invnum, + 'eventpart' => $_->eventpart, + 'status' => 'done', + } ) + } + qsearch( { + 'table' => 'part_bill_event', + 'hashref' => { 'payby' => 'DCLN', + 'disabled' => '', }, + } ) + ) { + + # don't run subsequent events if balance<=0 + last if $cust_pay_batch->cust_main->balance <= 0; + + warn " calling invoice event (". $part_bill_event->eventcode. ")\n" + if $DEBUG > 1; + my $cust_main = $cust_pay_batch->cust_main; #for callback + + my $error; + { + local $SIG{__DIE__}; # don't want Mason __DIE__ handler active + $error = eval $part_bill_event->eventcode; + } + + my $status = ''; + my $statustext = ''; + if ( $@ ) { + $status = 'failed'; + $statustext = $@; + } elsif ( $error ) { + $status = 'done'; + $statustext = $error; + } else { + $status = 'done' + } + + #add cust_bill_event + my $cust_bill_event = new FS::cust_bill_event { + 'invnum' => $cust_pay_batch->invnum, + 'eventpart' => $part_bill_event->eventpart, + '_date' => time, + 'status' => $status, + 'statustext' => $statustext, + }; + $error = $cust_bill_event->insert; + if ( $error ) { + # gah, even with transactions. + $dbh->commit if $oldAutoCommit; #well. + my $e = 'WARNING: Event run but database not updated - '. + 'error inserting cust_bill_event, invnum #'. $cust_pay_batch->invnum. + ', eventpart '. $part_bill_event->eventpart. + ": $error"; + warn $e; + return $e; + } + + } } + my $error = $new_cust_pay_batch->replace($cust_pay_batch); + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return "error updating status of paybatchnum $hash{'paybatchnum'}: $error\n"; + } + } $dbh->commit or die $dbh->errstr if $oldAutoCommit; diff --git a/FS/FS/part_bill_event.pm b/FS/FS/part_bill_event.pm index 98e15d4a2..2aef5bcce 100644 --- a/FS/FS/part_bill_event.pm +++ b/FS/FS/part_bill_event.pm @@ -144,7 +144,7 @@ sub check { } my $error = $self->ut_numbern('eventpart') - || $self->ut_enum('payby', [qw( CARD DCRD CHEK DCHK LECB BILL COMP )] ) + || $self->ut_enum('payby', [qw( CARD DCLN DCRD CHEK DCHK LECB BILL COMP )] ) || $self->ut_text('event') || $self->ut_anything('eventcode') || $self->ut_number('seconds') diff --git a/FS/FS/pay_batch.pm b/FS/FS/pay_batch.pm index 41b312c7a..7d9d9fb09 100644 --- a/FS/FS/pay_batch.pm +++ b/FS/FS/pay_batch.pm @@ -34,7 +34,11 @@ FS::Record. The following fields are currently supported: =item batchnum - primary key -=item status - +=item status - + +=item download - + +=item upload - =back @@ -109,7 +113,7 @@ sub check { =head1 BUGS -The author forgot to customize this manpage. +status is somewhat redundant now that download and upload exist =head1 SEE ALSO diff --git a/FS/FS/payby.pm b/FS/FS/payby.pm index 9f8b68918..72a876655 100644 --- a/FS/FS/payby.pm +++ b/FS/FS/payby.pm @@ -90,6 +90,11 @@ tie %hash, 'Tie::IxHash', shortname => 'Complimentary', longname => 'Complimentary', }, + 'DCLN' => { # This is only an event. + tinyname => 'declined', + shortname => 'Declined payment', + longname => 'Declined payment', + }, ; sub payby { diff --git a/README.1.7.0 b/README.1.7.0 index 69b395a34..c82c8ada9 100644 --- a/README.1.7.0 +++ b/README.1.7.0 @@ -8,9 +8,11 @@ ALTER TABLE cust_pay_batch ALTER COLUMN batchnum SET NOT NULL; ALTER TABLE cust_pay_batch ADD COLUMN payinfo varchar(512); UPDATE cust_pay_batch SET payinfo = cardnum; ALTER TABLE cust_pay_batch DROP COLUMN cardnum; +ALTER TABLE cust_pay_batch ALTER COLUMN exp DROP NOT NULL; ALTER TABLE h_cust_pay_batch ADD COLUMN payinfo varchar(512); UPDATE h_cust_pay_batch SET payinfo = cardnum; ALTER TABLE h_cust_pay_batch DROP COLUMN cardnum; +ALTER TABLE h_cust_pay_batch ALTER COLUMN exp DROP NOT NULL; make install-perl-modules run "freeside-upgrade username" to uprade your database schema diff --git a/httemplate/browse/cust_pay_batch.cgi b/httemplate/browse/cust_pay_batch.cgi index c7f0afe76..98ea2f5a2 100755 --- a/httemplate/browse/cust_pay_batch.cgi +++ b/httemplate/browse/cust_pay_batch.cgi @@ -1,12 +1,24 @@ -<%= include("/elements/header.html","Pending credit card batch", menubar( 'Main Menu' => $p,)) %> +<%= include("/elements/header.html","Credit card batch details", menubar( 'Main Menu' => $p,)) %> + +<% + +die "No batch specified (bad URL)!" unless $cgi->keywords; +my($query) = $cgi->keywords; +$query =~ /^(\d+)$/; +my $batchnum = $1; +my $pay_batch = qsearchs('pay_batch',{'batchnum'=>$batchnum}); +die "Batch not found!" unless $pay_batch; + +%>
Download batch in format
+ + +

@@ -15,25 +27,28 @@ Filename
Format

<% - my $statement = "SELECT SUM(amount) from cust_pay_batch"; + my $statement = "SELECT SUM(amount) from cust_pay_batch WHERE batchnum=". + $batchnum; my $sth = dbh->prepare($statement) or die dbh->errstr. "doing $statement"; $sth->execute or die "Error executing \"$statement\": ". $sth->errstr; my $total = $sth->fetchrow_arrayref->[0]; - my $c_statement = "SELECT COUNT(*) from cust_pay_batch"; + my $c_statement = "SELECT COUNT(*) from cust_pay_batch WHERE batchnum=". + $batchnum; my $c_sth = dbh->prepare($c_statement) or die dbh->errstr. "doing $c_statement"; $c_sth->execute or die "Error executing \"$c_statement\": ". $c_sth->errstr; my $cards = $c_sth->fetchrow_arrayref->[0]; %> <%= $cards %> credit card payments batched
-$<%= sprintf("%.2f", $total) %> total in pending batch
+$<%= sprintf("%.2f", $total) %> total in batch

<%= &table() %> @@ -45,11 +60,12 @@ $<%= sprintf("%.2f", $total) %> total in pending batch
Card Exp Amount + Status <% foreach my $cust_pay_batch ( sort { $a->paybatchnum <=> $b->paybatchnum } - qsearch('cust_pay_batch', {} ) + qsearch('cust_pay_batch', {'batchnum'=>$batchnum} ) ) { my $cardnum = $cust_pay_batch->payinfo; #$cardnum =~ s/.{4}$/xxxx/; @@ -71,6 +87,7 @@ foreach my $cust_pay_batch ( sort { $a->paybatchnum <=> $b->paybatchnum } <%= $cardnum %> <%= $exp %> $<%= $cust_pay_batch->amount %> + <%= $cust_pay_batch->status %> <% } %> diff --git a/httemplate/browse/pay_batch.cgi b/httemplate/browse/pay_batch.cgi new file mode 100755 index 000000000..66c86d676 --- /dev/null +++ b/httemplate/browse/pay_batch.cgi @@ -0,0 +1,54 @@ + +<%= include("/elements/header.html","Credit card batches", menubar( 'Main Menu' => $p,)) %> + +

+ +<% + my %statusmap = ('I'=>'In Transit', 'O'=>'Open', 'R'=>'Resolved'); +%> + +
+<%= &table() %> + + Batch + First Download + Last Upload + Item Count + Amount + Status + + +<% +foreach my $pay_batch ( sort { $b->batchnum <=> $a->batchnum } + qsearch('pay_batch', {} ) +) { + + my $statement = "SELECT SUM(amount) from cust_pay_batch WHERE batchnum=" . + $pay_batch->batchnum; + my $sth = dbh->prepare($statement) or die dbh->errstr. "doing $statement"; + $sth->execute or die "Error executing \"$statement\": ". $sth->errstr; + my $total = $sth->fetchrow_arrayref->[0]; + + my $c_statement = "SELECT COUNT(*) from cust_pay_batch WHERE batchnum=" . + $pay_batch->batchnum; + my $c_sth = dbh->prepare($c_statement) + or die dbh->errstr. "doing $c_statement"; + $c_sth->execute or die "Error executing \"$c_statement\": ". $c_sth->errstr; + my $cards = $c_sth->fetchrow_arrayref->[0]; + +%> + + + <%= $pay_batch->batchnum %> + <%= $pay_batch->download ? time2str("%a %b %e %T %Y", $pay_batch->download) : '' %> + <%= $pay_batch->upload ? time2str("%a %b %e %T %Y", $pay_batch->upload) : '' %> + <%= $cards %> + <%= $total %> + <%= $statusmap{$pay_batch->status} %> + + +<% } %> + + + + diff --git a/httemplate/docs/schema.html b/httemplate/docs/schema.html index d9e35efc7..cd4914a6c 100644 --- a/httemplate/docs/schema.html +++ b/httemplate/docs/schema.html @@ -203,11 +203,14 @@
  • batchnum
  • status +
  • download +
  • upload
  • cust_pay_batch - Pending batch members
    • paybatchnum
    • batchnum +
    • payby - CARD, CHEK, LECB, BILL, or COMP
    • payinfo - account number
    • exp - card expiration
    • amount @@ -222,6 +225,7 @@
    • state
    • zip
    • country +
    • status
  • cust_pkg - Customer billing items
      diff --git a/httemplate/misc/download-batch.cgi b/httemplate/misc/download-batch.cgi index 6172b1335..2c6481493 100644 --- a/httemplate/misc/download-batch.cgi +++ b/httemplate/misc/download-batch.cgi @@ -5,6 +5,13 @@ my $conf=new FS::Conf; #http_header('Content-Type' => 'text/comma-separated-values' ); #IE chokes http_header('Content-Type' => 'text/plain' ); +my $batchnum; +if ( $cgi->param('batchnum') =~ /^(\d+)$/ ) { + $batchnum = $1; +} else { + die "No batch number (bad URL) \n"; +} + my $format; if ( $cgi->param('format') =~ /^([\w\- ]+)$/ ) { $format = $1; @@ -16,11 +23,12 @@ my $oldAutoCommit = $FS::UID::AutoCommit; local $FS::UID::AutoCommit = 0; my $dbh = dbh; -my $pay_batch = qsearchs('pay_batch', {'status'=>'O'} ); +my $pay_batch = qsearchs('pay_batch', {'batchnum'=>$batchnum, 'status'=>'O'} ); die "No pending batch. \n" unless $pay_batch; my %batchhash = $pay_batch->hash; $batchhash{'status'} = 'I'; +$batchhash{'download'} = time unless $batchhash{'download'}; my $new = new FS::pay_batch \%batchhash; my $error = $new->replace($pay_batch); die "error updating batch status: $error\n" if $error; @@ -28,8 +36,10 @@ die "error updating batch status: $error\n" if $error; my $batchtotal=0; my $batchcount=0; -my (@date)=localtime(); -my $jdate = sprintf("%03d", $date[5] % 100).sprintf("%03d", $date[7]); +my (@date)=localtime($new->download); +my $jdate = sprintf("%03d", $date[5] % 100).sprintf("%03d", $date[7] + 1); +my $cdate = sprintf("%02d", $date[3]).sprintf("%02d", $date[4] + 1). + sprintf("%02d", $date[5] % 100); if ($format eq "BoM") { @@ -39,6 +49,14 @@ if ($format eq "BoM") { sprintf( "XD%03u%06u%-15s%-30s%09u%-12s \n",$typecode,$jdate,$shortname,$longname,$mybank,$myacct ) %><% +}elsif ($format eq "PAP"){ + + my($origid,$datacenter,$typecode,$shortname,$longname,$mybank,$myacct) = + $conf->config("batchconfig-$format"); + %><%= sprintf( "H%10sD%3s%06u%-15s%09u%-12s%04u%19s\n",$origid,$typecode,$cdate,$shortname,$mybank,$myacct,$pay_batch->batchnum,"") + + %><% + }elsif ($format eq "csv-td_canada_trust-merchant_pc_batch"){ # 1; }else{ @@ -61,7 +79,12 @@ for my $cust_pay_batch ( sort { $a->paybatchnum <=> $b->paybatchnum } if ($format eq "BoM") { my( $account, $aba ) = split( '@', $cust_pay_batch->payinfo ); - %><%= sprintf( "D%010u%09u%-12s%-29s%-19s\n",$cust_pay_batch->amount*100,$aba,$account,$cust_pay_batch->payname,$cust_pay_batch->invnum %><% + %><%= sprintf( "D%010.0f%09u%-12s%-29s%-19s\n",$cust_pay_batch->amount*100,$aba,$account,$cust_pay_batch->payname,$cust_pay_batch->paybatchnum) %><% + + } elsif ($format eq "PAP"){ + + my( $account, $aba ) = split( '@', $cust_pay_batch->payinfo ); + %><%= sprintf( "D%-23s%06u%-19s%09u%-12s%010.0f\n",$cust_pay_batch->payname,$cdate,$cust_pay_batch->paybatchnum,$aba,$account,$cust_pay_batch->amount*100) %><% } elsif ($format eq "csv-td_canada_trust-merchant_pc_batch") { @@ -75,9 +98,13 @@ for my $cust_pay_batch ( sort { $a->paybatchnum <=> $b->paybatchnum } if ($format eq "BoM") { - %><%= sprintf( "YD%08u%014u%56s\n",$batchcount,$batchtotal*100,"" ). + %><%= sprintf( "YD%08u%014.0f%56s\n",$batchcount,$batchtotal*100,"" ). sprintf( "Z%014u%05u%014u%05u%41s\n",$batchtotal*100,$batchcount,"0","0","" ) %><% +} elsif ($format eq "PAP"){ + + %><%= sprintf( "T%08u%014.0f%57s\n",$batchcount,$batchtotal*100,"" ) %><% + } elsif ($format eq "csv-td_canada_trust-merchant_pc_batch"){ #1; } else { -- 2.11.0