From: Jonathan Prykop Date: Fri, 5 Feb 2016 21:16:12 +0000 (-0600) Subject: RT#39586 Manual check refunds cannot be unapplied X-Git-Url: http://git.freeside.biz/gitweb/?p=freeside.git;a=commitdiff_plain;h=9192ae1275e778f890d75c07066ddd2e4cabaa26 RT#39586 Manual check refunds cannot be unapplied --- 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 objects that will be deleted by L +(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. + +=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 objects that will be deleted by L +(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. + +=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; + + 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; + + 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 ? ' ' . 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 ? ' ' . 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 ? ' ' . 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 ? ' ' . emt('refunds') : '') + ) + if $refund_to_unapply; +}