X-Git-Url: http://git.freeside.biz/gitweb/?p=freeside.git;a=blobdiff_plain;f=FS%2FFS%2Fcust_pay_batch.pm;h=171ec9fcfae5af7040599de357a6d585f6b80714;hp=f321bb2fee90b355452dcbabb7a7c60485c055e4;hb=f9a181e4c2e505df84de16190ee3b75011326f3f;hpb=a014f2e125028a5a80c0587f36df5e865b70b47f diff --git a/FS/FS/cust_pay_batch.pm b/FS/FS/cust_pay_batch.pm index f321bb2fe..171ec9fcf 100644 --- a/FS/FS/cust_pay_batch.pm +++ b/FS/FS/cust_pay_batch.pm @@ -2,12 +2,14 @@ package FS::cust_pay_batch; use strict; use vars qw( @ISA $DEBUG ); +use Carp qw( confess ); +use Business::CreditCard 0.28; use FS::Record qw(dbh qsearch qsearchs); use FS::payinfo_Mixin; -use FS::part_bill_event qw(due_events); -use Business::CreditCard 0.28; +use FS::cust_main; +use FS::cust_bill; -@ISA = qw( FS::Record FS::payinfo_Mixin ); +@ISA = qw( FS::payinfo_Mixin FS::Record ); # 1 is mostly method/subroutine entry and options # 2 traces progress of some operations @@ -33,7 +35,7 @@ FS::cust_pay_batch - Object methods for batch cards $error = $record->check; - $error = $record->retriable; + #deprecated# $error = $record->retriable; =head1 DESCRIPTION @@ -202,19 +204,27 @@ sub cust_main { qsearchs( 'cust_main', { 'custnum' => $self->custnum } ); } -=item retriable +#you know what, screw this in the new world of events. we should be able to +#get the event defs to retry (remove once.pm condition, add every.pm) without +#mucking about with statuses of previous cust_event records. right? +# +#=item retriable +# +#Marks the corresponding event (see L) for this batched +#credit card payment as retriable. Useful if the corresponding financial +#institution account was declined for temporary reasons and/or a manual +#retry is desired. +# +#Implementation details: For the named customer's invoice, changes the +#statustext of the 'done' (without statustext) event to 'retriable.' +# +#=cut -Marks the corresponding event (see L) for this batched -credit card payment as retriable. Useful if the corresponding financial -institution account was declined for temporary reasons and/or a manual -retry is desired. +sub retriable { -Implementation details: For the named customer's invoice, changes the -statustext of the 'done' (without statustext) event to 'retriable.' + confess "deprecated method cust_pay_batch->retriable called; try removing ". + "the once condition and adding an every condition?"; -=cut - -sub retriable { my $self = shift; local $SIG{HUP} = 'IGNORE'; #Hmm @@ -250,6 +260,104 @@ sub retriable { ''; } +=item approve PAYBATCH + +Approve this payment. This will replace the existing record with the +same paybatchnum, set its status to 'Approved', and generate a payment +record (L). This should only be called from the batch +import process. + +=cut + +sub approve { + # to break up the Big Wall of Code that is import_results + my $new = shift; + my $paybatch = shift; + my $paybatchnum = $new->paybatchnum; + my $old = qsearchs('cust_pay_batch', { paybatchnum => $paybatchnum }) + or return "paybatchnum $paybatchnum not found"; + return "paybatchnum $paybatchnum already resolved ('".$old->status."')" + if $old->status; + $new->status('Approved'); + my $error = $new->replace($old); + if ( $error ) { + return "error updating status of paybatchnum $paybatchnum: $error\n"; + } + my $cust_pay = new FS::cust_pay ( { + 'custnum' => $new->custnum, + 'payby' => $new->payby, + 'paybatch' => $paybatch, + 'payinfo' => $new->payinfo || $old->payinfo, + 'paid' => $new->paid, + '_date' => $new->_date, + 'usernum' => $new->usernum, + } ); + $error = $cust_pay->insert; + if ( $error ) { + return "error inserting payment for paybatchnum $paybatchnum: $error\n"; + } + $cust_pay->cust_main->apply_payments; + return; +} + +=item decline + +Decline this payment. This will replace the existing record with the +same paybatchnum, set its status to 'Declined', and run collection events +as appropriate. This should only be called from the batch import process. + +=cut + +sub decline { + my $new = shift; + my $conf = new FS::Conf; + + my $paybatchnum = $new->paybatchnum; + my $old = qsearchs('cust_pay_batch', { paybatchnum => $paybatchnum }) + or return "paybatchnum $paybatchnum not found"; + if ( $old->status ) { + # Handle the case where payments are rejected after the batch has been + # approved. Only if manual approval is enabled. + if ( $conf->exists('batch-manual_approval') + and lc($old->status) eq 'approved' ) { + # Void the payment + my $cust_pay = qsearchs('cust_pay', { + custnum => $new->custnum, + paybatch => $new->batchnum + }); + if ( !$cust_pay ) { + # should never happen... + return "failed to revoke paybatchnum $paybatchnum, payment not found"; + } + $cust_pay->void('Returned payment'); + } + else { + # normal case: refuse to do anything + return "paybatchnum $paybatchnum already resolved ('".$old->status."')"; + } + } # !$old->status + $new->status('Declined'); + my $error = $new->replace($old); + if ( $error ) { + return "error updating status of paybatchnum $paybatchnum: $error\n"; + } + my $due_cust_event = $new->cust_main->due_cust_event( + 'eventtable' => 'cust_pay_batch', + 'objects' => [ $new ], + ); + if ( !ref($due_cust_event) ) { + return $due_cust_event; + } + # XXX breaks transaction integrity + foreach my $cust_event (@$due_cust_event) { + next unless $cust_event->test_conditions; + if ( my $error = $cust_event->do_event() ) { + return $error; + } + } + return; +} + =back =head1 BUGS