X-Git-Url: http://git.freeside.biz/gitweb/?p=freeside.git;a=blobdiff_plain;f=FS%2FFS%2Fcust_pay_batch.pm;h=6e76b3462070f7484d24c1784be212a3f114ab5c;hp=da003d85e431777ac8b54d27885206b31999f982;hb=772656864b377bbd2ef2febd40891ef1206b5be0;hpb=b0e67356e3a16101eb06a12e2a48cc6dc4233c29 diff --git a/FS/FS/cust_pay_batch.pm b/FS/FS/cust_pay_batch.pm index da003d85e..6e76b3462 100644 --- a/FS/FS/cust_pay_batch.pm +++ b/FS/FS/cust_pay_batch.pm @@ -3,7 +3,7 @@ use base qw( FS::payinfo_Mixin FS::cust_main_Mixin FS::Record ); use strict; use vars qw( $DEBUG ); -use Carp qw( confess ); +use Carp qw( carp confess ); use Business::CreditCard 0.28; use FS::Record qw(dbh qsearch qsearchs); @@ -63,6 +63,8 @@ following fields are currently supported: =item payname - name on card +=item paytype - account type ((personal|business) (checking|savings)) + =item first - name =item last - name @@ -129,6 +131,8 @@ and replace methods. sub check { my $self = shift; + my $conf = new FS::Conf; + my $error = $self->ut_numbern('paybatchnum') || $self->ut_numbern('trancode') #deprecated @@ -137,7 +141,9 @@ sub check { || $self->ut_number('custnum') || $self->ut_text('address1') || $self->ut_textn('address2') - || $self->ut_text('city') + || ($conf->exists('cust_main-no_city_in_address') + ? $self->ut_textn('city') + : $self->ut_text('city')) || $self->ut_textn('state') ; @@ -152,6 +158,18 @@ sub check { $error = $self->payinfo_check(); return $error if $error; + if ( $self->payby eq 'CHEK' ) { + # because '' is on the list of paytypes: + my $paytype = $self->paytype or return "Bank account type required"; + if (grep { $_ eq $paytype} FS::cust_payby->paytypes) { + #ok + } else { + return "Bank account type '$paytype' is not allowed" + } + } else { + $self->set('paytype', ''); + } + if ( $self->exp eq '' ) { return "Expiration date required" unless $self->payby =~ /^(CHEK|DCHK|WEST)$/; @@ -221,7 +239,7 @@ sub expmmyy { =item pay_batch -Returns the payment batch this payment belongs to (L). =cut @@ -279,10 +297,12 @@ sub approve { 'custnum' => $new->custnum, 'payby' => $new->payby, 'payinfo' => $new->payinfo || $old->payinfo, + 'paymask' => $new->mask_payinfo, 'paid' => $new->paid, '_date' => $new->_date, 'usernum' => $new->usernum, 'batchnum' => $new->batchnum, + 'invnum' => $old->invnum, 'gatewaynum' => $opt{'gatewaynum'}, 'processor' => $opt{'processor'}, 'auth' => $opt{'auth'}, @@ -344,14 +364,8 @@ sub decline { } $cust_pay->void($reason); } - elsif ( lc($old->status) eq 'declined' ) { - # batch files from RBC can have multiple lines for one decline - # if this causes problems elsewhere, try hacking pay_batch/RBC.pm instead - return ''; - } else { # normal case: refuse to do anything - # should never happen...only statuses are approved or declined return "cannot decline paybatchnum $paybatchnum, already resolved ('".$old->status."')"; } } # !$old->status @@ -410,12 +424,23 @@ sub request_item { $self->payinfo =~ /(\d+)@(\d+)/; # or else what? $payment{account_number} = $1; $payment{routing_code} = $2; - $payment{account_type} = $cust_main->paytype; + $payment{account_type} = $self->paytype; # XXX what if this isn't their regular payment method? } else { die "unsupported BatchPayment method: ".$pay_batch->payby; } + my $recurring; + if ( $cust_main->status =~ /^active|suspended|ordered$/ ) { + if ( $self->payinfo_used ) { + $recurring = 'S'; # subsequent + } else { + $recurring = 'F'; # first use + } + } else { + $recurring = 'N'; # non-recurring + } + Business::BatchPayment->create(Item => # required action => 'payment', @@ -431,10 +456,93 @@ sub request_item { ( map { $_ => $location->$_ } qw(address2 city state country zip) ), invoice_number => $self->invnum, + recurring_billing => $recurring, %payment, ); } +=item process_unbatch_and_delete + +L run as a queued job, accepts I<$job> and I<$param>. + +=cut + +sub process_unbatch_and_delete { + my ($job, $param) = @_; + my $self = qsearchs('cust_pay_batch',{ 'paybatchnum' => scalar($param->{'paybatchnum'}) }) + or die 'Could not find paybatchnum ' . $param->{'paybatchnum'}; + my $error = $self->unbatch_and_delete; + die $error if $error; + return ''; +} + +=item unbatch_and_delete + +May only be called on a record with an empty status and an associated +L with a status of 'O' (not yet in transit.) Deletes all associated +records from L and then deletes this record. +If there is an error, returns the error, otherwise returns false. + +=cut + +sub unbatch_and_delete { + my $self = shift; + + return 'Cannot unbatch a cust_pay_batch with status ' . $self->status + if $self->status; + + my $pay_batch = qsearchs('pay_batch',{ 'batchnum' => $self->batchnum }) + or return 'Cannot find associated pay_batch record'; + + return 'Cannot unbatch from a pay_batch with status ' . $pay_batch->status + if $pay_batch->status ne 'O'; + + 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; + + # have not generated actual payments yet, so should be safe to delete + foreach my $cust_bill_pay_batch ( + qsearch('cust_bill_pay_batch',{ 'paybatchnum' => $self->paybatchnum }) + ) { + my $error = $cust_bill_pay_batch->delete; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + } + + my $error = $self->delete; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + + $dbh->commit or die $dbh->errstr if $oldAutoCommit; + ''; + +} + +=item cust_bill + +Returns the invoice linked to this batched payment. Deprecated, will be +removed. + +=cut + +sub cust_bill { + carp "FS::cust_pay_batch->cust_bill is deprecated"; + my $self = shift; + $self->invnum ? qsearchs('cust_bill', { invnum => $self->invnum }) : ''; +} + =back =head1 BUGS