X-Git-Url: http://git.freeside.biz/gitweb/?p=freeside.git;a=blobdiff_plain;f=FS%2FFS%2Fcust_pay_batch.pm;h=8059f1ca2e0be297d297ae2fbcd064bb87d5c984;hp=7c5c6c40457b43345d6b978dbb46902bfbb544b8;hb=d20581bcbf2809d5c2969d773b16a0c8714a6dec;hpb=6cd87c0d3b5280446301c647fa5f1ec5a593fa3f diff --git a/FS/FS/cust_pay_batch.pm b/FS/FS/cust_pay_batch.pm index 7c5c6c404..8059f1ca2 100644 --- a/FS/FS/cust_pay_batch.pm +++ b/FS/FS/cust_pay_batch.pm @@ -2,7 +2,7 @@ package FS::cust_pay_batch; use strict; use vars qw( @ISA ); -use FS::Record; +use FS::Record qw(dbh qsearchs); use Business::CreditCard; @ISA = qw( FS::Record ); @@ -35,7 +35,7 @@ following fields are currently supported: =over 4 -=item trancode - 77 for charges +=item paybatchnum - primary key (automatically assigned) =item cardnum @@ -117,7 +117,8 @@ sub check { my $self = shift; my $error = - $self->ut_numbern('trancode') + $self->ut_numbern('paybatchnum') + || $self->ut_numbern('trancode') #depriciated || $self->ut_number('cardnum') || $self->ut_money('amount') || $self->ut_number('invnum') @@ -125,7 +126,7 @@ sub check { || $self->ut_text('address1') || $self->ut_textn('address2') || $self->ut_text('city') - || $self->ut_text('state') + || $self->ut_textn('state') ; return $error if $error; @@ -172,23 +173,214 @@ sub check { $self->payname($1); } - $self->zip =~ /^\s*(\w[\w\-\s]{3,8}\w)\s*$/ - or return "Illegal zip: ". $self->zip; - $self->zip($1); + #$self->zip =~ /^\s*(\w[\w\-\s]{3,8}\w)\s*$/ + # or return "Illegal zip: ". $self->zip; + #$self->zip($1); - $self->country =~ /^(\w\w)$/ or return "Illegal \w\wy"; + $self->country =~ /^(\w\w)$/ or return "Illegal country: ". $self->country; $self->country($1); + $error = $self->ut_zip('zip', $self->country); + return $error if $error; + #check invnum, custnum, ? - ''; #no error + $self->SUPER::check; +} + +=item cust_main + +Returns the customer (see L) for this batched credit card +payment. + +=cut + +sub cust_main { + my $self = shift; + qsearchs( 'cust_main', { 'custnum' => $self->custnum } ); } =back -=head1 VERSION +=head1 SUBROUTINES + +=over 4 + +=item import_results + +=cut + +sub import_results { + use Time::Local; + use FS::cust_pay; + eval "use Text::CSV_XS;"; + die $@ if $@; +# + my $param = shift; + my $fh = $param->{'filehandle'}; + my $format = $param->{'format'}; + my $paybatch = $param->{'paybatch'}; + + my @fields; + my $end_condition; + my $end_hook; + my $hook; + my $approved_condition; + my $declined_condition; + + if ( $format eq 'csv-td_canada_trust-merchant_pc_batch' ) { + + @fields = ( + 'paybatchnum', # Reference#: Invoice number of the transaction + 'paid', # Amount: Amount of the transaction. Dollars and cents + # with no decimal entered. + '', # Card Type: 0 - MCrd, 1 - Visa, 2 - AMEX, 3 - Discover, + # 4 - Insignia, 5 - Diners/EnRoute, 6 - JCB + '_date', # Transaction Date: Date the Transaction was processed + 'time', # Transaction Time: Time the transaction was processed + 'payinfo', # Card Number: Card number for the transaction + '', # Expiry Date: Expiry date of the card + '', # Auth#: Authorization number entered for force post + # transaction + 'type', # Transaction Type: 0 - purchase, 40 - refund, + # 20 - force post + 'result', # Processing Result: 3 - Approval, + # 4 - Declined/Amount over limit, + # 5 - Invalid/Expired/stolen card, + # 6 - Comm Error + '', # Terminal ID: Terminal ID used to process the transaction + ); + + $end_condition = sub { + my $hash = shift; + $hash->{'type'} eq '0BC'; + }; + + $end_hook = sub { + my( $hash, $total) = @_; + $total = sprintf("%.2f", $total); + my $batch_total = sprintf("%.2f", $hash->{'paybatchnum'} / 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 ); + $hash->{'_date'} = timelocal( substr($hash->{'time'}, 4, 2), + substr($hash->{'time'}, 2, 2), + substr($hash->{'time'}, 0, 2), + substr($hash->{'_date'}, 6, 2), + substr($hash->{'_date'}, 4, 2)-1, + substr($hash->{'_date'}, 0, 4)-1900, ); + }; + + $approved_condition = sub { + my $hash = shift; + $hash->{'type'} eq '0' && $hash->{'result'} == 3; + }; + + $declined_condition = sub { + my $hash = shift; + $hash->{'type'} eq '0' && ( $hash->{'result'} == 4 + || $hash->{'result'} == 5 ); + }; + + + } else { + return "Unknown format $format"; + } + + my $csv = new Text::CSV_XS; + + local $SIG{HUP} = 'IGNORE'; + local $SIG{INT} = 'IGNORE'; + local $SIG{QUIT} = 'IGNORE'; + local $SIG{TERM} = 'IGNORE'; + local $SIG{TSTP} = 'IGNORE'; + local $SIG{PIPE} = 'IGNORE'; + + my $oldAutoCommit = $FS::UID::AutoCommit; + local $FS::UID::AutoCommit = 0; + my $dbh = dbh; + + my $total = 0; + my $line; + while ( defined($line=<$fh>) ) { -$Id: cust_pay_batch.pm,v 1.1 1999-08-04 09:03:53 ivan Exp $ + next if $line =~ /^\s*$/; #skip blank lines + + $csv->parse($line) or do { + $dbh->rollback if $oldAutoCommit; + return "can't parse: ". $csv->error_input(); + }; + + my @values = $csv->fields(); + my %hash; + foreach my $field ( @fields ) { + my $value = shift @values; + next unless $field; + $hash{$field} = $value; + } + + if ( &{$end_condition}(\%hash) ) { + my $error = &{$end_hook}(\%hash, $total); + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + last; + } + + my $cust_pay_batch = + qsearchs('cust_pay_batch', { 'paybatchnum' => $hash{'paybatchnum'} } ); + unless ( $cust_pay_batch ) { + $dbh->rollback if $oldAutoCommit; + return "unknown paybatchnum $hash{'paybatchnum'}\n"; + } + my $custnum = $cust_pay_batch->custnum, + + my $error = $cust_pay_batch->delete; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return "error removing paybatchnum $hash{'paybatchnum'}: $error\n"; + } + + &{$hook}(\%hash); + + if ( &{$approved_condition}(\%hash) ) { + + my $cust_pay = new FS::cust_pay ( { + 'custnum' => $custnum, + 'payby' => 'CARD', + 'paybatch' => $paybatch, + map { $_ => $hash{$_} } (qw( paid _date payinfo )), + } ); + $error = $cust_pay->insert; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return "error adding payment paybatchnum $hash{'paybatchnum'}: $error\n"; + } + $total += $hash{'paid'}; + + $cust_pay->cust_main->apply_payments; + + } elsif ( &{$declined_condition}(\%hash) ) { + + #this should be configurable... if anybody else ever uses batches + $cust_pay_batch->cust_main->suspend; + + } + + } + + $dbh->commit or die $dbh->errstr if $oldAutoCommit; + ''; + +} + +=back =head1 BUGS