From 42a1267af992831cb8069835a18b8672a5f9afcb Mon Sep 17 00:00:00 2001 From: ivan Date: Wed, 4 Aug 2010 19:14:50 +0000 Subject: [PATCH] show cust_pay_pending attempted payments on customer payment history, RT#8815 --- FS/FS/Record.pm | 17 ++++---- FS/FS/cust_main.pm | 47 +++++++++++++++++++--- httemplate/view/cust_main/payment_history.html | 10 +++++ .../payment_history/attempted_payment.html | 41 +++++++++++++++++++ 4 files changed, 102 insertions(+), 13 deletions(-) create mode 100644 httemplate/view/cust_main/payment_history/attempted_payment.html diff --git a/FS/FS/Record.pm b/FS/FS/Record.pm index 44bc28d46..bc075dde9 100644 --- a/FS/FS/Record.pm +++ b/FS/FS/Record.pm @@ -2801,21 +2801,22 @@ sub h_date { $h ? $h->history_date : ''; } -=item scalar_sql SQL +=item scalar_sql SQL [ PLACEHOLDER, ... ] -A class method with a propensity for becoming an instance method. This -method executes the sql statement represented by SQL and returns a scalar -representing the result. Don't ask for rows -- you get the first column -of the first row. Don't give me bogus SQL or I'll die on you. +A class or object method. Executes the sql statement represented by SQL and +returns a scalar representing the result: the first column of the first row. -Returns an empty string in the event of no rows. +Dies on bogus SQL. Returns an empty string if no row is returned. + +Typically used for statments which return a single value such as "SELECT +COUNT(*) FROM table WHERE something" OR "SELECT column FROM table WHERE key = ?" =cut sub scalar_sql { - my($self, $sql ) = ( shift, shift ); + my($self, $sql) = (shift, shift); my $sth = dbh->prepare($sql) or die dbh->errstr; - $sth->execute + $sth->execute(@_) or die "Unexpected error executing statement $sql: ". $sth->errstr; my $scalar = $sth->fetchrow_arrayref->[0]; defined($scalar) ? $scalar : ''; diff --git a/FS/FS/cust_main.pm b/FS/FS/cust_main.pm index 47eccd7f8..b1bf1791c 100644 --- a/FS/FS/cust_main.pm +++ b/FS/FS/cust_main.pm @@ -7097,6 +7097,26 @@ sub cust_pay_pending { ); } +=item cust_pay_pending_attempt + +Returns all payment attempts / declined payments for this customer, as pending +payments objects (see L), with status "done" but without +a corresponding payment (see L). + +=cut + +sub cust_pay_pending_attempt { + my $self = shift; + return $self->num_cust_pay_pending_attempt unless wantarray; + sort { $a->_date <=> $b->_date } + qsearch( 'cust_pay_pending', { + 'custnum' => $self->custnum, + 'status' => 'done', + 'paynum' => '', + }, + ); +} + =item num_cust_pay_pending Returns the number of pending payments (see L) for this @@ -7107,11 +7127,28 @@ cust_pay_pending method is used in a scalar context. sub num_cust_pay_pending { my $self = shift; - my $sql = " SELECT COUNT(*) FROM cust_pay_pending ". - " WHERE custnum = ? AND status != 'done' "; - my $sth = dbh->prepare($sql) or die dbh->errstr; - $sth->execute($self->custnum) or die $sth->errstr; - $sth->fetchrow_arrayref->[0]; + $self->scalar_sql( + " SELECT COUNT(*) FROM cust_pay_pending ". + " WHERE custnum = ? AND status != 'done' ", + $self->custnum + ); +} + +=item num_cust_pay_pending_attempt + +Returns the number of pending payments (see L) for this +customer, with status "done" but without a corresp. Also called automatically when the +cust_pay_pending method is used in a scalar context. + +=cut + +sub num_cust_pay_pending_attempt { + my $self = shift; + $self->scalar_sql( + " SELECT COUNT(*) FROM cust_pay_pending ". + " WHERE custnum = ? AND status = 'done' AND paynum IS NULL", + $self->custnum + ); } =item cust_refund diff --git a/httemplate/view/cust_main/payment_history.html b/httemplate/view/cust_main/payment_history.html index 0dc4c41d5..60d33ac23 100644 --- a/httemplate/view/cust_main/payment_history.html +++ b/httemplate/view/cust_main/payment_history.html @@ -422,6 +422,16 @@ foreach my $cust_pay_void ($cust_main->cust_pay_void) { } +#declined payments +foreach my $cust_pay_pending ($cust_main->cust_pay_pending_attempt) { + push @history, { + 'date' => $cust_pay_pending->_date, + 'desc' => include('payment_history/attempted_payment.html', $cust_pay_pending, %opt ), + 'void_payment' => $cust_pay_pending->paid, #?? + #'target' => $target, #XXX + }; +} + #credits (some false laziness w/payments) foreach my $cust_credit ($cust_main->cust_credit) { push @history, { diff --git a/httemplate/view/cust_main/payment_history/attempted_payment.html b/httemplate/view/cust_main/payment_history/attempted_payment.html new file mode 100644 index 000000000..554aa737d --- /dev/null +++ b/httemplate/view/cust_main/payment_history/attempted_payment.html @@ -0,0 +1,41 @@ +Payment attempt <% $info |h %> +<%init> + +my( $cust_pay_pending, %opt ) = @_; + +my $date_format = $opt{'date_format'} || '%m/%d/%Y'; + +my $curuser = $FS::CurrentUser::CurrentUser; + +my $payby = $cust_pay_pending->payby; + +my $payinfo; +if ( $payby eq 'CARD' ) { + $payinfo = $cust_pay_pending->paymask; +} elsif ( $payby eq 'CHEK' ) { + my( $account, $aba ) = split('@', $cust_pay_pending->paymask ); + $payinfo = "ABA $aba, Acct #$account"; +} else { + $payinfo = $cust_pay_pending->payinfo; +} + +$payby =~ s/^BILL$/Check #/ if $payinfo; +$payby =~ s/^CHEK$/Electronic check /; +$payby =~ s/^PREP$/Prepaid card /; +$payby =~ s/^CARD$/Credit card #/; +$payby =~ s/^COMP$/Complimentary by /; +$payby =~ s/^CASH$/Cash/; +$payby =~ s/^WEST$/Western Union/; +$payby =~ s/^MCRD$/Manual credit card/; +$payby =~ s/^BILL$//; +my $info = $payby ? "($payby$payinfo)" : ''; + +if ( $opt{'pkg-balances'} && $cust_pay_pending->pkgnum ) { + my $cust_pkg = qsearchs('cust_pkg', { 'pkgnum'=>$cust_pay_pending->pkgnum } ); + $info .= ' for '. $cust_pkg->pkg_label_long; +} + +$info .= ': '. $cust_pay_pending->statustext + if length($cust_pay_pending->statustext); + + -- 2.11.0