summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Prykop <jonathan@freeside.biz>2016-02-05 15:16:12 -0600
committerJonathan Prykop <jonathan@freeside.biz>2016-02-23 08:35:56 -0600
commit1bb85d2484b3d9f45c2b1142951503ff1c54e2e9 (patch)
treefb77f0b5d02a031859afbf1e4e72700b619422ed
parent7d44517cf03a15c0b65b77c01720f3758374af22 (diff)
RT#39586 Manual check refunds cannot be unapplied
-rw-r--r--FS/FS/cust_credit.pm52
-rw-r--r--FS/FS/cust_pay.pm54
-rwxr-xr-xhttemplate/misc/unapply-cust_credit_refund.cgi18
-rwxr-xr-xhttemplate/misc/unapply-cust_pay_refund.cgi18
-rw-r--r--httemplate/view/cust_main/payment_history/credit.html25
-rw-r--r--httemplate/view/cust_main/payment_history/payment.html24
6 files changed, 174 insertions, 17 deletions
diff --git a/FS/FS/cust_credit.pm b/FS/FS/cust_credit.pm
index 6b21d69b9..a598b37a3 100644
--- a/FS/FS/cust_credit.pm
+++ b/FS/FS/cust_credit.pm
@@ -1028,6 +1028,58 @@ sub credit_lineitems {
}
+### refund_to_unapply/unapply_refund false laziness with FS::cust_pay
+
+=item refund_to_unapply
+
+Returns L<FS::cust_credit_refund> objects that will be deleted by L</unapply_refund>
+(all currently applied refunds that aren't closed.)
+Returns empty list if credit itself is closed.
+
+=cut
+
+sub refund_to_unapply {
+ my $self = shift;
+ return () if $self->closed;
+ qsearch({
+ 'table' => 'cust_credit_refund',
+ 'hashref' => { 'crednum' => $self->crednum },
+ 'addl_from' => 'LEFT JOIN cust_refund USING (refundnum)',
+ 'extra_sql' => "AND (cust_refund.closed = '' OR cust_refund.closed IS NULL)",
+ });
+}
+
+=item unapply_refund
+
+Deletes all objects returned by L</refund_to_unapply>.
+
+=cut
+
+sub unapply_refund {
+ my $self = shift;
+
+ local $SIG{HUP} = 'IGNORE';
+ local $SIG{INT} = 'IGNORE';
+ local $SIG{QUIT} = 'IGNORE';
+ local $SIG{TERM} = 'IGNORE';
+ local $SIG{TSTP} = 'IGNORE';
+ local $SIG{PIPE} = 'IGNORE';
+
+ my $oldAutoCommit = $FS::UID::AutoCommit;
+ local $FS::UID::AutoCommit = 0;
+
+ foreach my $cust_credit_refund ($self->refund_to_unapply) {
+ my $error = $cust_credit_refund->delete;
+ if ($error) {
+ dbh->rollback if $oldAutoCommit;
+ return $error;
+ }
+ }
+
+ dbh->commit or die dbh->errstr if $oldAutoCommit;
+ return '';
+}
+
=back
=head1 SUBROUTINES
diff --git a/FS/FS/cust_pay.pm b/FS/FS/cust_pay.pm
index 4d06862d6..af76b8990 100644
--- a/FS/FS/cust_pay.pm
+++ b/FS/FS/cust_pay.pm
@@ -903,6 +903,58 @@ sub refund {
return '';
}
+### refund_to_unapply/unapply_refund false laziness with FS::cust_credit
+
+=item refund_to_unapply
+
+Returns L<FS::cust_pay_refund> objects that will be deleted by L</unapply_refund>
+(all currently applied refunds that aren't closed.)
+Returns empty list if payment itself is closed.
+
+=cut
+
+sub refund_to_unapply {
+ my $self = shift;
+ return () if $self->closed;
+ qsearch({
+ 'table' => 'cust_pay_refund',
+ 'hashref' => { 'paynum' => $self->paynum },
+ 'addl_from' => 'LEFT JOIN cust_refund USING (refundnum)',
+ 'extra_sql' => "AND (cust_refund.closed = '' OR cust_refund.closed IS NULL)",
+ });
+}
+
+=item unapply_refund
+
+Deletes all objects returned by L</refund_to_unapply>.
+
+=cut
+
+sub unapply_refund {
+ my $self = shift;
+
+ local $SIG{HUP} = 'IGNORE';
+ local $SIG{INT} = 'IGNORE';
+ local $SIG{QUIT} = 'IGNORE';
+ local $SIG{TERM} = 'IGNORE';
+ local $SIG{TSTP} = 'IGNORE';
+ local $SIG{PIPE} = 'IGNORE';
+
+ my $oldAutoCommit = $FS::UID::AutoCommit;
+ local $FS::UID::AutoCommit = 0;
+
+ foreach my $cust_pay_refund ($self->refund_to_unapply) {
+ my $error = $cust_pay_refund->delete;
+ if ($error) {
+ dbh->rollback if $oldAutoCommit;
+ return $error;
+ }
+ }
+
+ dbh->commit or die dbh->errstr if $oldAutoCommit;
+ return '';
+}
+
=back
=head1 CLASS METHODS
@@ -990,7 +1042,7 @@ sub batch_insert {
Returns an SQL fragment to retreive the unapplied amount.
-=cut
+=cut
sub unapplied_sql {
my ($class, $start, $end) = @_;
diff --git a/httemplate/misc/unapply-cust_credit_refund.cgi b/httemplate/misc/unapply-cust_credit_refund.cgi
new file mode 100755
index 000000000..55a81b055
--- /dev/null
+++ b/httemplate/misc/unapply-cust_credit_refund.cgi
@@ -0,0 +1,18 @@
+<% $cgi->redirect($p. "view/cust_main.cgi?custnum=". $custnum. ";show=payment_history") %>
+<%init>
+
+die "access denied"
+ unless $FS::CurrentUser::CurrentUser->access_right('Unapply credit');
+
+#untaint crednum
+my($query) = $cgi->keywords;
+$query =~ /^(\d+)$/ || die "Illegal crednum";
+my $crednum = $1;
+
+my $cust_credit = qsearchs('cust_credit', { 'crednum' => $crednum } );
+my $custnum = $cust_credit->custnum;
+
+my $error = $cust_credit->unapply_refund;
+errorpage($error) if $error;
+
+</%init>
diff --git a/httemplate/misc/unapply-cust_pay_refund.cgi b/httemplate/misc/unapply-cust_pay_refund.cgi
new file mode 100755
index 000000000..9e470b6e4
--- /dev/null
+++ b/httemplate/misc/unapply-cust_pay_refund.cgi
@@ -0,0 +1,18 @@
+<% $cgi->redirect($p. "view/cust_main.cgi?custnum=". $custnum. ";show=payment_history") %>
+<%init>
+
+die "access denied"
+ unless $FS::CurrentUser::CurrentUser->access_right('Unapply payment');
+
+#untaint paynum
+my($query) = $cgi->keywords;
+$query =~ /^(\d+)$/ || die "Illegal paynum";
+my $paynum = $1;
+
+my $cust_pay = qsearchs('cust_pay', { 'paynum' => $paynum } );
+my $custnum = $cust_pay->custnum;
+
+my $error = $cust_pay->unapply_refund;
+errorpage($error) if $error;
+
+</%init>
diff --git a/httemplate/view/cust_main/payment_history/credit.html b/httemplate/view/cust_main/payment_history/credit.html
index db2e5e582..85911a03f 100644
--- a/httemplate/view/cust_main/payment_history/credit.html
+++ b/httemplate/view/cust_main/payment_history/credit.html
@@ -139,14 +139,23 @@ $void = ' ('.
&& $opt{'Void credit'};
my $unapply = '';
-$unapply = areyousure_link("${p}misc/unapply-cust_credit.cgi?".$cust_credit->crednum,
- emt('Are you sure you want to unapply this credit?'),
- '',
- emt('unapply')
- )
- if $cust_credit->closed !~ /^Y/i
- && scalar(@cust_credit_bill)
- && $opt{'Unapply credit'};
+
+if ($opt{'Unapply credit'} && !$cust_credit->closed) {
+ my $refund_to_unapply = $cust_credit->refund_to_unapply;
+ my $usepre = $refund_to_unapply && @cust_credit_bill;
+ $unapply = areyousure_link("${p}misc/unapply-cust_credit.cgi?".$cust_credit->crednum,
+ emt('Are you sure you want to unapply this credit from invoices?'),
+ emt('Keep this credit, but dissociate it from the invoices it is currently applied against'),
+ emt('unapply') . ($usepre ? '&nbsp;' . emt('invoices') : '')
+ )
+ if @cust_credit_bill;
+ $unapply .= areyousure_link("${p}misc/unapply-cust_credit_refund.cgi?".$cust_credit->crednum,
+ emt('Are you sure you want to unapply this credit from refunds?'),
+ emt('Keep this credit, but dissociate it from the refunds it is currently applied to'),
+ emt('unapply') . ($usepre ? '&nbsp;' . emt('refunds') : '')
+ )
+ if $refund_to_unapply;
+}
my $reason = $cust_credit->reason;
$reason = $reason ? " ($reason)" : '';
diff --git a/httemplate/view/cust_main/payment_history/payment.html b/httemplate/view/cust_main/payment_history/payment.html
index 6c93f7b27..16b91c2f2 100644
--- a/httemplate/view/cust_main/payment_history/payment.html
+++ b/httemplate/view/cust_main/payment_history/payment.html
@@ -197,13 +197,21 @@ $void = ' ('.
);
my $unapply = '';
-$unapply = areyousure_link("${p}misc/unapply-cust_pay.cgi?".$cust_pay->paynum,
- emt('Are you sure you want to unapply this payment?'),
- emt('Keep this payment, but dissociate it from the invoices it is currently applied against'),
- emt('unapply')
- )
- if $cust_pay->closed !~ /^Y/i
- && scalar(@cust_bill_pay)
- && $opt{'Unapply payment'};
+if ($opt{'Unapply payment'} && !$cust_pay->closed) {
+ my $refund_to_unapply = $cust_pay->refund_to_unapply;
+ my $usepre = $refund_to_unapply && @cust_bill_pay;
+ $unapply = areyousure_link("${p}misc/unapply-cust_pay.cgi?".$cust_pay->paynum,
+ emt('Are you sure you want to unapply this payment from invoices?'),
+ emt('Keep this payment, but dissociate it from the invoices it is currently applied against'),
+ emt('unapply') . ($usepre ? '&nbsp;' . emt('invoices') : '')
+ )
+ if @cust_bill_pay;
+ $unapply .= areyousure_link("${p}misc/unapply-cust_pay_refund.cgi?".$cust_pay->paynum,
+ emt('Are you sure you want to unapply this payment from refunds?'),
+ emt('Keep this payment, but dissociate it from the refunds it is currently applied to'),
+ emt('unapply') . ($usepre ? '&nbsp;' . emt('refunds') : '')
+ )
+ if $refund_to_unapply;
+}
</%init>