summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--FS/FS/AccessRight.pm2
-rw-r--r--FS/FS/Conf.pm7
-rw-r--r--FS/FS/cust_credit_refund.pm19
-rw-r--r--FS/FS/cust_pay_refund.pm15
-rw-r--r--FS/FS/cust_refund.pm42
-rwxr-xr-xhttemplate/misc/delete-cust_refund.cgi17
-rw-r--r--httemplate/view/cust_main/payment_history.html16
7 files changed, 107 insertions, 11 deletions
diff --git a/FS/FS/AccessRight.pm b/FS/FS/AccessRight.pm
index 4a6da083a..038cb4113 100644
--- a/FS/FS/AccessRight.pm
+++ b/FS/FS/AccessRight.pm
@@ -138,6 +138,8 @@ assigned to users and/or groups.
'Delete payment', #aka. deletepayments - Enable deletion of unclosed payments. Be very careful! Only delete payments that were data-entry errors, not adjustments. Optionally specify one or more comma-separated email addresses to be notified when a payment is deleted.
+ 'Delete refund',
+
###
# customer credit rights
###
diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm
index f2fda8016..0d680b297 100644
--- a/FS/FS/Conf.pm
+++ b/FS/FS/Conf.pm
@@ -496,6 +496,13 @@ httemplate/docs/config.html
},
{
+ 'key' => 'deleterefunds',
+ 'section' => 'billing',
+ 'description' => 'Enable deletion of unclosed refunds. Be very careful! Only delete refunds that were data-entry errors, not adjustments.',
+ 'type' => 'checkbox',
+ },
+
+ {
'key' => 'unapplypayments',
'section' => 'deprecated',
'description' => '<B>DEPRECATED</B>, now controlled by ACLs. Used to enable "unapplication" of unclosed payments.',
diff --git a/FS/FS/cust_credit_refund.pm b/FS/FS/cust_credit_refund.pm
index 36c77aa59..f237efed2 100644
--- a/FS/FS/cust_credit_refund.pm
+++ b/FS/FS/cust_credit_refund.pm
@@ -70,20 +70,27 @@ otherwise returns false.
sub insert {
my $self = shift;
- my $error = $self->SUPER::insert;
- return $error if $error;
-
- '';
+ return "Can't apply refund to closed credit"
+ if $self->cust_credit->closed =~ /^Y/i;
+ return "Can't apply credit to closed refund"
+ if $self->cust_refund->closed =~ /^Y/i;
+ $self->SUPER::insert(@_);
}
=item delete
-Currently unimplemented (accounting reasons).
+Remove this cust_credit_refund from the database. If there is an error,
+returns the error, otherwise returns false.
=cut
sub delete {
- return "Can't (yet?) delete cust_credit_refund records!";
+ my $self = shift;
+ return "Can't remove refund from closed credit"
+ if $self->cust_credit->closed =~ /^Y/i;
+ return "Can't remove credit from closed refund"
+ if $self->cust_refund->closed =~ /^Y/i;
+ $self->SUPER::delete(@_);
}
=item replace OLD_RECORD
diff --git a/FS/FS/cust_pay_refund.pm b/FS/FS/cust_pay_refund.pm
index 15e0e533a..cb9dbcef2 100644
--- a/FS/FS/cust_pay_refund.pm
+++ b/FS/FS/cust_pay_refund.pm
@@ -73,15 +73,26 @@ sub table { 'cust_pay_refund'; }
Adds this cust_pay_refund to the database. If there is an error, returns the
error, otherwise returns false.
+=cut
+
+sub insert {
+ my $self = shift;
+ return "Can't apply refund to closed payment"
+ if $self->cust_pay->closed =~ /^Y/i;
+ return "Can't apply payment to closed refund"
+ if $self->cust_refund->closed =~ /^Y/i;
+ $self->SUPER::insert(@_);
+}
+
=item delete
=cut
sub delete {
my $self = shift;
- return "Can't apply refund to closed payment"
+ return "Can't remove refund from closed payment"
if $self->cust_pay->closed =~ /^Y/i;
- return "Can't apply closed refund"
+ return "Can't remove payment from closed refund"
if $self->cust_refund->closed =~ /^Y/i;
$self->SUPER::delete(@_);
}
diff --git a/FS/FS/cust_refund.pm b/FS/FS/cust_refund.pm
index 3f17f9aa2..9cd9bf845 100644
--- a/FS/FS/cust_refund.pm
+++ b/FS/FS/cust_refund.pm
@@ -166,14 +166,52 @@ sub insert {
=item delete
-Currently unimplemented (accounting reasons).
+Unless the closed flag is set, deletes this refund and all associated
+applications (see L<FS::cust_credit_refund> and L<FS::cust_pay_refund>).
=cut
sub delete {
my $self = shift;
return "Can't delete closed refund" if $self->closed =~ /^Y/i;
- $self->SUPER::delete(@_);
+
+ 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;
+ my $dbh = dbh;
+
+ foreach my $cust_credit_refund ( $self->cust_credit_refund ) {
+ my $error = $cust_credit_refund->delete;
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return $error;
+ }
+ }
+
+ foreach my $cust_pay_refund ( $self->cust_pay_refund ) {
+ my $error = $cust_pay_refund->delete;
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return $error;
+ }
+ }
+
+ my $error = $self->SUPER::delete(@_);
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return $error;
+ }
+
+ $dbh->commit or die $dbh->errstr if $oldAutoCommit;
+
+ '';
+
}
=item replace OLD_RECORD
diff --git a/httemplate/misc/delete-cust_refund.cgi b/httemplate/misc/delete-cust_refund.cgi
new file mode 100755
index 000000000..3e44560d0
--- /dev/null
+++ b/httemplate/misc/delete-cust_refund.cgi
@@ -0,0 +1,17 @@
+%
+%
+%#untaint refundnum
+%my($query) = $cgi->keywords;
+%$query =~ /^(\d+)$/ || die "Illegal refundnum";
+%my $refundnum = $1;
+%
+%my $cust_refund = qsearchs('cust_refund',{'refundnum'=>$refundnum});
+%my $custnum = $cust_refund->custnum;
+%
+%my $error = $cust_refund->delete;
+%eidiot($error) if $error;
+%
+%print $cgi->redirect($p. "view/cust_main.cgi?". $custnum);
+%
+%
+
diff --git a/httemplate/view/cust_main/payment_history.html b/httemplate/view/cust_main/payment_history.html
index a23ca9ac7..43c55e8c9 100644
--- a/httemplate/view/cust_main/payment_history.html
+++ b/httemplate/view/cust_main/payment_history.html
@@ -372,9 +372,23 @@
% $payby =~ s/^CHEK$/Electronic check /;
% $payby =~ s/^(CARD|COMP)$/$1 /;
%
+% my $delete = '';
+% if ( $cust_refund->closed !~ /^Y/i
+% && $conf->exists('deleterefunds')
+% && $curuser->access_right('Delete refund')
+% )
+% {
+% $delete = qq! (<A HREF="javascript:areyousure('!.
+% qq!${p}misc/delete-cust_refund.cgi?!. $cust_refund->refundnum.
+% qq!', 'Are you sure you want to delete this refund?')"!.
+% qq! TITLE="Delete this refund from the database completely - not recommended"!.
+% qq!>delete</A>)!;
+% }
+%
% push @history, {
% 'date' => $cust_refund->_date,
-% 'desc' => "Refund ($payby$payinfo) by ". $cust_refund->otaker,
+% 'desc' => "Refund ($payby$payinfo) by ". $cust_refund->otaker. "<BR>".
+% $delete,
% 'refund' => $cust_refund->refund,
% };
%