summaryrefslogtreecommitdiff
path: root/FS
diff options
context:
space:
mode:
Diffstat (limited to 'FS')
-rw-r--r--FS/FS/AccessRight.pm2
-rw-r--r--FS/FS/cust_main.pm40
-rw-r--r--FS/FS/cust_pay_pending.pm83
3 files changed, 120 insertions, 5 deletions
diff --git a/FS/FS/AccessRight.pm b/FS/FS/AccessRight.pm
index fe10572ca..93660e236 100644
--- a/FS/FS/AccessRight.pm
+++ b/FS/FS/AccessRight.pm
@@ -152,6 +152,8 @@ tie my %rights, 'Tie::IxHash',
'Resend invoices', #NEWNEW
'View customer tax exemptions', #yow
'View customer batched payments', #NEW
+ 'View customer pending payments', #NEW
+ 'Edit customer pending payments', #NEW
'View customer billing events', #NEW
],
diff --git a/FS/FS/cust_main.pm b/FS/FS/cust_main.pm
index 1d234a765..7d68536a4 100644
--- a/FS/FS/cust_main.pm
+++ b/FS/FS/cust_main.pm
@@ -3691,7 +3691,7 @@ sub realtime_bop {
'country' => ( exists($options{'country'})
? $options{'country'}
: $self->country ),
- 'referer' => 'http://cleanwhisker.420.am/',
+ 'referer' => 'http://cleanwhisker.420.am/', #XXX fix referer :/
'email' => $email,
'phone' => $self->daytime || $self->night,
%content, #after
@@ -3847,6 +3847,7 @@ sub realtime_bop {
$cust_pay_pending->status('done');
$cust_pay_pending->statustext('captured');
+ $cust_pay_pending->paynum($cust_pay->paynum);
my $cpp_done_err = $cust_pay_pending->replace;
if ( $cpp_done_err ) {
@@ -4196,7 +4197,7 @@ sub realtime_refund_bop {
'password' => $password,
'order_number' => $order_number,
'amount' => $amount,
- 'referer' => 'http://cleanwhisker.420.am/',
+ 'referer' => 'http://cleanwhisker.420.am/', #XXX fix referer :/
);
$content{authorization} = $auth
if length($auth); #echeck/ACH transactions have an order # but no auth
@@ -5349,6 +5350,41 @@ sub cust_pay_batch {
qsearch( 'cust_pay_batch', { 'custnum' => $self->custnum } )
}
+=item cust_pay_pending
+
+Returns all pending payments (see L<FS::cust_pay_pending>) for this customer
+(without status "done").
+
+=cut
+
+sub cust_pay_pending {
+ my $self = shift;
+ return $self->num_cust_pay_pending unless wantarray;
+ sort { $a->_date <=> $b->_date }
+ qsearch( 'cust_pay_pending', {
+ 'custnum' => $self->custnum,
+ 'status' => { op=>'!=', value=>'done' },
+ },
+ );
+}
+
+=item num_cust_pay_pending
+
+Returns the number of pending payments (see L<FS::cust_pay_pending>) for this
+customer (without status "done"). Also called automatically when the
+cust_pay_pending method is used in a scalar context.
+
+=cut
+
+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];
+}
+
=item cust_refund
Returns all the refunds (see L<FS::cust_refund>) for this customer.
diff --git a/FS/FS/cust_pay_pending.pm b/FS/FS/cust_pay_pending.pm
index 7469720f4..bbabd247e 100644
--- a/FS/FS/cust_pay_pending.pm
+++ b/FS/FS/cust_pay_pending.pm
@@ -3,12 +3,12 @@ package FS::cust_pay_pending;
use strict;
use vars qw( @ISA @encrypted_fields );
use FS::Record qw( qsearch qsearchs dbh ); #dbh for _upgrade_data
-use FS::payby;
-use FS::payinfo_Mixin;
+use FS::payinfo_transaction_Mixin;
+use FS::cust_main_Mixin;
use FS::cust_main;
use FS::cust_pay;
-@ISA = qw(FS::Record FS::payinfo_Mixin);
+@ISA = qw( FS::payinfo_transaction_Mixin FS::cust_main_Mixin FS::Record );
@encrypted_fields = ('payinfo');
@@ -215,6 +215,83 @@ sub check {
$self->SUPER::check;
}
+#these two are kind-of false laziness w/cust_main::realtime_bop
+#(currently only used when resolving pending payments manually)
+
+=item insert_cust_pay
+
+Sets the status of this pending pament to "done" (with statustext
+"captured (manual)"), and inserts a payment record (see L<FS::cust_pay>).
+
+Currently only used when resolving pending payments manually.
+
+=cut
+
+sub insert_cust_pay {
+ my $self = shift;
+
+ my $cust_pay = new FS::cust_pay ( {
+ 'custnum' => $self->custnum,
+ 'paid' => $self->paid,
+ '_date' => $self->_date, #better than passing '' for now
+ 'payby' => $self->payby,
+ 'payinfo' => $self->payinfo,
+ 'paybatch' => $self->paybatch,
+ 'paydate' => $self->paydate,
+ } );
+
+ my $oldAutoCommit = $FS::UID::AutoCommit;
+ local $FS::UID::AutoCommit = 0;
+ my $dbh = dbh;
+
+ #start a transaction, insert the cust_pay and set cust_pay_pending.status to done in a single transction
+
+ my $error = $cust_pay->insert;#($options{'manual'} ? ( 'manual' => 1 ) : () );
+
+ if ( $error ) {
+ # gah.
+ $dbh->rollback or die $dbh->errstr if $oldAutoCommit;
+ return $error;
+ }
+
+ $self->status('done');
+ $self->statustext('captured (manual)');
+ $self->paynum($cust_pay->paynum);
+ my $cpp_done_err = $self->replace;
+
+ if ( $cpp_done_err ) {
+
+ $dbh->rollback or die $dbh->errstr if $oldAutoCommit;
+ return $cpp_done_err;
+
+ } else {
+
+ $dbh->commit or die $dbh->errstr if $oldAutoCommit;
+ return ''; #no error
+
+ }
+
+}
+
+=item decline
+
+Sets the status of this pending pament to "done" (with statustext
+"declined (manual)").
+
+Currently only used when resolving pending payments manually.
+
+=cut
+
+sub decline {
+ my $self = shift;
+
+ #could send decline email too? doesn't seem useful in manual resolution
+
+ $self->status('done');
+ $self->statustext("declined (manual)");
+ $self->replace;
+}
+
# _upgrade_data
#
# Used by FS::Upgrade to migrate to a new database.