X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2Fcust_pay.pm;h=eee263a1d4fe3722df422b5c6978cc6bf0af8f0d;hb=b1d445f94514a29e5d4753839798b0291d89aee3;hp=69bcd87176c916d5f83264f648277bcd0e9cab0c;hpb=40a7b3dc653e099f7bd0bd762b649b04c4432db2;p=freeside.git diff --git a/FS/FS/cust_pay.pm b/FS/FS/cust_pay.pm index 69bcd8717..eee263a1d 100644 --- a/FS/FS/cust_pay.pm +++ b/FS/FS/cust_pay.pm @@ -1,7 +1,9 @@ package FS::cust_pay; use strict; -use vars qw( @ISA $DEBUG $me $conf @encrypted_fields +use base qw( FS::otaker_Mixin FS::payinfo_transaction_Mixin FS::cust_main_Mixin + FS::Record ); +use vars qw( $DEBUG $me $conf @encrypted_fields $unsuspendauto $ignore_noapply ); use Date::Format; @@ -20,9 +22,7 @@ use FS::cust_main; use FS::cust_pkg; use FS::cust_pay_void; -@ISA = qw( FS::payinfo_transaction_Mixin FS::cust_main_Mixin FS::Record ); - -$DEBUG = 1; +$DEBUG = 0; $me = '[FS::cust_pay]'; @@ -80,9 +80,9 @@ L and L for conversion functions. Amount of this payment -=item otaker +=item usernum -order taker (assigned automatically, see L) +order taker (see L) =item payby @@ -179,7 +179,7 @@ sub insert { $error = $self->SUPER::insert; if ( $error ) { $dbh->rollback if $oldAutoCommit; - return "error inserting $self: $error"; + return "error inserting cust_pay: $error"; } if ( $self->invnum ) { @@ -192,11 +192,11 @@ sub insert { $error = $cust_bill_pay->insert(%options); if ( $error ) { if ( $ignore_noapply ) { - warn "warning: error inserting $cust_bill_pay: $error ". + warn "warning: error inserting cust_bill_pay: $error ". "(ignore_noapply flag set; inserting cust_pay record anyway)\n"; } else { $dbh->rollback if $oldAutoCommit; - return "error inserting $cust_bill_pay: $error"; + return "error inserting cust_bill_pay: $error"; } } } @@ -381,7 +381,7 @@ sub check { || $self->ut_numbern('custnum') || $self->ut_numbern('_date') || $self->ut_money('paid') - || $self->ut_alpha('otaker') + || $self->ut_alphan('otaker') || $self->ut_textn('paybatch') || $self->ut_textn('payunique') || $self->ut_enum('closed', [ '', 'Y' ]) @@ -446,76 +446,82 @@ sub send_receipt { my $conf = new FS::Conf; - return '' - unless $conf->exists('payment_receipt_email') - && grep { $_ !~ /^(POST|FAX)$/ } $cust_main->invoicing_list; + my @invoicing_list = $cust_main->invoicing_list_emailonly; + return '' unless @invoicing_list; $cust_bill ||= ($cust_main->cust_bill)[-1]; #rather inefficient though? if ( ( exists($opt->{'manual'}) && $opt->{'manual'} ) - || ! $conf->exists('invoice_html_statement') + || ! $conf->exists('invoice_html_statement') # XXX msg_template || ! $cust_bill ) { - my $receipt_template = new Text::Template ( - TYPE => 'ARRAY', - SOURCE => [ map "$_\n", $conf->config('payment_receipt_email') ], - ) or do { - warn "can't create payment receipt template: $Text::Template::ERROR"; - return ''; - }; - - my @invoicing_list = grep { $_ !~ /^(POST|FAX)$/ } - $cust_main->invoicing_list; - - my $payby = $self->payby; - my $payinfo = $self->payinfo; - $payby =~ s/^BILL$/Check/ if $payinfo; - if ( $payby eq 'CARD' || $payby eq 'CHEK' ) { - $payinfo = $self->paymask - } else { - $payinfo = $self->decrypt($payinfo); - } - $payby =~ s/^CHEK$/Electronic check/; - - my %fill_in = ( - 'date' => time2str("%a %B %o, %Y", $self->_date), - 'name' => $cust_main->name, - 'paynum' => $self->paynum, - 'paid' => sprintf("%.2f", $self->paid), - 'payby' => ucfirst(lc($payby)), - 'payinfo' => $payinfo, - 'balance' => $cust_main->balance, - 'company_name' => $conf->config('company_name', $cust_main->agentnum), - ); + my $error = ''; - if ( $opt->{'cust_pkg'} ) { - $fill_in{'pkg'} = $opt->{'cust_pkg'}->part_pkg->pkg; - #setup date, other things? + if( $conf->exists('payment_receipt_msgnum') ) { + my $msg_template = + FS::msg_template->by_key($conf->config('payment_receipt_msgnum')); + $error = $msg_template->send('cust_main'=> $cust_main, 'object'=> $self); } + elsif ( $conf->exists('payment_receipt_email') ) { + my $receipt_template = new Text::Template ( + TYPE => 'ARRAY', + SOURCE => [ map "$_\n", $conf->config('payment_receipt_email') ], + ) or do { + warn "can't create payment receipt template: $Text::Template::ERROR"; + return ''; + }; - send_email( - 'from' => $conf->config('invoice_from', $cust_main->agentnum), - #invoice_from??? well as good as any - 'to' => \@invoicing_list, - 'subject' => 'Payment receipt', - 'body' => [ $receipt_template->fill_in( HASH => \%fill_in ) ], - ); - - } else { + my $payby = $self->payby; + my $payinfo = $self->payinfo; + $payby =~ s/^BILL$/Check/ if $payinfo; + if ( $payby eq 'CARD' || $payby eq 'CHEK' ) { + $payinfo = $self->paymask + } else { + $payinfo = $self->decrypt($payinfo); + } + $payby =~ s/^CHEK$/Electronic check/; + + my %fill_in = ( + 'date' => time2str("%a %B %o, %Y", $self->_date), + 'name' => $cust_main->name, + 'paynum' => $self->paynum, + 'paid' => sprintf("%.2f", $self->paid), + 'payby' => ucfirst(lc($payby)), + 'payinfo' => $payinfo, + 'balance' => $cust_main->balance, + 'company_name' => $conf->config('company_name', $cust_main->agentnum), + ); + + if ( $opt->{'cust_pkg'} ) { + $fill_in{'pkg'} = $opt->{'cust_pkg'}->part_pkg->pkg; + #setup date, other things? + } - my $queue = new FS::queue { - 'paynum' => $self->paynum, - 'job' => 'FS::cust_bill::queueable_email', - }; + $error = send_email( + 'from' => $conf->config('invoice_from', $cust_main->agentnum), + #invoice_from??? well as good as any + 'to' => \@invoicing_list, + 'subject' => 'Payment receipt', + 'body' => [ $receipt_template->fill_in( HASH => \%fill_in ) ], + ); - $queue->insert( - 'invnum' => $cust_bill->invnum, - 'template' => 'statement', - ); + } + else { # no payment_receipt_msgnum or payment_receipt_email - } + my $queue = new FS::queue { + 'paynum' => $self->paynum, + 'job' => 'FS::cust_bill::queueable_email', + }; + $queue->insert( + 'invnum' => $cust_bill->invnum, + 'template' => 'statement', + ); + } + + warn "send_receipt: $error\n" if $error; + } #$opt{manual} || no invoice_html_statement || customer has no invoices } =item cust_bill_pay @@ -527,6 +533,7 @@ payment. sub cust_bill_pay { my $self = shift; + map { $_ } #return $self->num_cust_bill_pay unless wantarray; sort { $a->_date <=> $b->_date || $a->invnum <=> $b->invnum } qsearch( 'cust_bill_pay', { 'paynum' => $self->paynum } ) @@ -542,6 +549,7 @@ payment. sub cust_pay_refund { my $self = shift; + map { $_ } #return $self->num_cust_pay_refund unless wantarray; sort { $a->_date <=> $b->_date } qsearch( 'cust_pay_refund', { 'paynum' => $self->paynum } ) ; @@ -657,17 +665,23 @@ Returns an SQL fragment to retreive the unapplied amount. =cut sub unapplied_sql { - #my $class = shift; + my ($class, $start, $end) = @_; + my $bill_start = $start ? "AND cust_bill_pay._date <= $start" : ''; + my $bill_end = $end ? "AND cust_bill_pay._date > $end" : ''; + my $refund_start = $start ? "AND cust_pay_refund._date <= $start" : ''; + my $refund_end = $end ? "AND cust_pay_refund._date > $end" : ''; "paid - COALESCE( ( SELECT SUM(amount) FROM cust_bill_pay - WHERE cust_pay.paynum = cust_bill_pay.paynum ) + WHERE cust_pay.paynum = cust_bill_pay.paynum + $bill_start $bill_end ) ,0 ) - COALESCE( ( SELECT SUM(amount) FROM cust_pay_refund - WHERE cust_pay.paynum = cust_pay_refund.paynum ) + WHERE cust_pay.paynum = cust_pay_refund.paynum + $refund_start $refund_end ) ,0 ) "; @@ -685,9 +699,14 @@ sub _upgrade_data { #class method warn "$me upgrading $class\n" if $DEBUG; + ## + # otaker/ivan upgrade + ## + #not the most efficient, but hey, it only has to run once my $where = "WHERE ( otaker IS NULL OR otaker = '' OR otaker = 'ivan' ) ". + " AND usernum IS NULL ". " AND 0 < ( SELECT COUNT(*) FROM cust_main ". " WHERE cust_main.custnum = cust_pay.custnum ) "; @@ -739,6 +758,45 @@ sub _upgrade_data { #class method } + ### + # payinfo N/A upgrade + ### + + #XXX remove the 'N/A (tokenized)' part (or just this entire thing) + + my @na_cust_pay = qsearch( { + 'table' => 'cust_pay', + 'hashref' => {}, #could be encrypted# { 'payinfo' => 'N/A' }, + 'extra_sql' => "WHERE ( payinfo = 'N/A' OR paymask = 'N/AA' OR paymask = 'N/A (tokenized)' ) AND payby IN ( 'CARD', 'CHEK' )", + } ); + + foreach my $na ( @na_cust_pay ) { + + next unless $na->payinfo eq 'N/A'; + + my $cust_pay_pending = + qsearchs('cust_pay_pending', { 'paynum' => $na->paynum } ); + unless ( $cust_pay_pending ) { + warn " *** WARNING: not-yet recoverable N/A card for payment ". + $na->paynum. " (no cust_pay_pending)\n"; + next; + } + $na->$_($cust_pay_pending->$_) for qw( payinfo paymask ); + my $error = $na->replace; + if ( $error ) { + warn " *** WARNING: Error updating payinfo for payment paynum ". + $na->paynun. ": $error\n"; + next; + } + + } + + ### + # otaker->usernum upgrade + ### + + $class->_upgrade_otaker(%opts); + } =back