summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorivan <ivan>2010-08-04 19:14:50 +0000
committerivan <ivan>2010-08-04 19:14:50 +0000
commit42a1267af992831cb8069835a18b8672a5f9afcb (patch)
tree8bc80fce58538c2bf47c6b281fc35de63030ea32
parent543cb4d548e42826e377c4790e28bb730d7ddf66 (diff)
show cust_pay_pending attempted payments on customer payment history, RT#8815
-rw-r--r--FS/FS/Record.pm17
-rw-r--r--FS/FS/cust_main.pm47
-rw-r--r--httemplate/view/cust_main/payment_history.html10
-rw-r--r--httemplate/view/cust_main/payment_history/attempted_payment.html41
4 files changed, 102 insertions, 13 deletions
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<FS::cust_pay_pending>), with status "done" but without
+a corresponding payment (see L<FS::cust_pay>).
+
+=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<FS::cust_pay_pending>) 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<FS::cust_pay_pending>) 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 @@
+<I>Payment attempt <% $info |h %></I>
+<%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);
+
+</%init>