From bec3b6c2bf97d66b992866d7ee7295f1f05452e6 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Wed, 1 Aug 2012 14:01:14 -0700 Subject: [PATCH] invoice voiding, RT#18677 --- FS/FS/AccessRight.pm | 7 +- FS/FS/access_right.pm | 9 ++- FS/FS/cust_bill_pkg_void.pm | 74 ++++++++++++++++++++-- FS/FS/cust_bill_void.pm | 61 +++++++++++++++--- httemplate/misc/process/void-cust_bill.html | 6 +- httemplate/misc/unvoid-cust_bill_void.html | 25 ++++++++ httemplate/misc/unvoid-cust_pay_void.cgi | 2 +- httemplate/misc/void-cust_pay.cgi | 2 +- .../view/cust_main/payment_history/payment.html | 2 +- .../cust_main/payment_history/voided_invoice.html | 8 ++- .../cust_main/payment_history/voided_payment.html | 2 +- 11 files changed, 171 insertions(+), 27 deletions(-) create mode 100755 httemplate/misc/unvoid-cust_bill_void.html diff --git a/FS/FS/AccessRight.pm b/FS/FS/AccessRight.pm index ebf66e64c..b41ec2fe2 100644 --- a/FS/FS/AccessRight.pm +++ b/FS/FS/AccessRight.pm @@ -178,6 +178,7 @@ tie my %rights, 'Tie::IxHash', 'View invoices', 'Resend invoices', #NEWNEW 'Void invoices', + 'Unvoid invoices', 'Delete invoices', 'View customer tax exemptions', #yow 'Add customer tax adjustment', #new, but no need to phase in @@ -228,11 +229,11 @@ tie my %rights, 'Tie::IxHash', ### # customer voiding rights.. ### - 'Customer void rights' => [ + 'Customer payment void rights' => [ { rightname=>'Credit card void', desc=>'Enable local-only voiding of echeck payments in addition to refunds against the payment gateway.' }, #aka. cc-void { rightname=>'Echeck void', desc=>'Enable local-only voiding of echeck payments in addition to refunds against the payment gateway.' }, #aka. echeck-void - 'Regular void', - { rightname=>'Unvoid', desc=>'Enable unvoiding of voided payments' }, #aka. unvoid + 'Void payments', + { rightname=>'Unvoid payments', desc=>'Enable unvoiding of voided payments' }, #aka. unvoid ], diff --git a/FS/FS/access_right.pm b/FS/FS/access_right.pm index bc57364d2..dc9f9978d 100644 --- a/FS/FS/access_right.pm +++ b/FS/FS/access_right.pm @@ -152,6 +152,8 @@ sub _upgrade_data { # class method 'Process payment' => [ 'Process credit card payment', 'Process Echeck payment' ], 'Post refund' => [ 'Post check refund', 'Post cash refund' ], 'Refund payment' => [ 'Refund credit card payment', 'Refund Echeck payment' ], + 'Regular void' => [ 'Void payments' ], + 'Unvoid' => [ 'Unvoid payments', 'Unvoid invoices' ], ); foreach my $oldright (keys %migrate) { @@ -174,9 +176,10 @@ sub _upgrade_data { # class method die $error if $error; } - #after the WEST stuff is sorted, etc. - #my $error = $old->delete; - #die $error if $error; + unless ( $oldright =~ / (payment|refund)$/ ) { #after the WEST stuff is sorted + my $error = $old->delete; + die $error if $error; + } } diff --git a/FS/FS/cust_bill_pkg_void.pm b/FS/FS/cust_bill_pkg_void.pm index 7855d58c6..b7c6feed5 100644 --- a/FS/FS/cust_bill_pkg_void.pm +++ b/FS/FS/cust_bill_pkg_void.pm @@ -2,11 +2,12 @@ package FS::cust_bill_pkg_void; use base qw( FS::TemplateItem_Mixin FS::Record ); use strict; -use FS::Record qw( qsearch qsearchs ); +use FS::Record qw( qsearch qsearchs dbh fields ); use FS::cust_bill_void; use FS::cust_bill_pkg_detail_void; use FS::cust_bill_pkg_display_void; use FS::cust_bill_pkg_discount_void; +use FS::cust_bill_pkg; =head1 NAME @@ -129,21 +130,84 @@ sub discount_table { 'cust_bill_pkg_discount_void'; } Adds this record to the database. If there is an error, returns the error, otherwise returns false. +=item unvoid + +"Un-void"s this line item: Deletes the voided line item from the database and +adds back a normal line item (and related tables). + =cut +sub unvoid { + 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; + my $dbh = dbh; + + my $cust_bill_pkg = new FS::cust_bill_pkg ( { + map { $_ => $self->get($_) } fields('cust_bill_pkg') + } ); + my $error = $cust_bill_pkg->insert; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + + foreach my $table (qw( + cust_bill_pkg_detail + cust_bill_pkg_display + cust_bill_pkg_discount + cust_bill_pkg_tax_location + cust_bill_pkg_tax_rate_location + cust_tax_exempt_pkg + )) { + + foreach my $voided ( + qsearch($table.'_void', { billpkgnum=>$self->billpkgnum }) + ) { + + my $class = 'FS::'.$table; + my $unvoid = $class->new( { + map { $_ => $voided->get($_) } fields($table) + }); + my $error = $unvoid->insert || $voided->delete; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + + } + + } + + $error = $self->delete; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + + $dbh->commit or die $dbh->errstr if $oldAutoCommit; + + ''; + +} + =item delete Delete this record from the database. -=cut - =item replace OLD_RECORD Replaces the OLD_RECORD with this one in the database. If there is an error, returns the error, otherwise returns false. -=cut - =item check Checks all fields to make sure this is a valid record. If there is diff --git a/FS/FS/cust_bill_void.pm b/FS/FS/cust_bill_void.pm index cd6a9e13b..cce77b3aa 100644 --- a/FS/FS/cust_bill_void.pm +++ b/FS/FS/cust_bill_void.pm @@ -2,11 +2,12 @@ package FS::cust_bill_void; use base qw( FS::Template_Mixin FS::cust_main_Mixin FS::otaker_Mixin FS::Record ); use strict; -use FS::Record qw( qsearch qsearchs ); +use FS::Record qw( qsearch qsearchs dbh fields ); use FS::cust_main; use FS::cust_statement; use FS::access_user; use FS::cust_bill_pkg_void; +use FS::cust_bill; =head1 NAME @@ -117,7 +118,55 @@ otherwise returns false. =cut -# the insert method can be inherited from FS::Record +=item unvoid + +"Un-void"s this invoice: Deletes the voided invoice from the database and adds +back a normal invoice (and related tables). + +=cut + +sub unvoid { + 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; + my $dbh = dbh; + + my $cust_bill = new FS::cust_bill ( { + map { $_ => $self->get($_) } fields('cust_bill') + } ); + my $error = $cust_bill->insert; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + + foreach my $cust_bill_pkg_void ( $self->cust_bill_pkg ) { + my $error = $cust_bill_pkg_void->unvoid; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + } + + $error = $self->delete; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + + $dbh->commit or die $dbh->errstr if $oldAutoCommit; + + ''; + +} =item delete @@ -125,8 +174,6 @@ Delete this record from the database. =cut -# the delete method can be inherited from FS::Record - =item replace OLD_RECORD Replaces the OLD_RECORD with this one in the database. If there is an error, @@ -134,8 +181,6 @@ returns the error, otherwise returns false. =cut -# the replace method can be inherited from FS::Record - =item check Checks all fields to make sure this is a valid voided invoice. If there is @@ -144,9 +189,6 @@ and replace methods. =cut -# the check method should currently be supplied - FS::Record contains some -# data checking routines - sub check { my $self = shift; @@ -230,7 +272,6 @@ sub cust_bill_pkg { #actually cust_bill_pkg_void objects sub enable_previous { 0 } - =back =head1 BUGS diff --git a/httemplate/misc/process/void-cust_bill.html b/httemplate/misc/process/void-cust_bill.html index f2930ec01..899901a50 100755 --- a/httemplate/misc/process/void-cust_bill.html +++ b/httemplate/misc/process/void-cust_bill.html @@ -2,7 +2,11 @@ % $cgi->param('error', $error); <% $cgi->redirect(popurl(1). "void-cust_bill.html?". $cgi->query_string ) %> %} else { -<% $cgi->redirect(popurl(3). "view/cust_main.cgi?". $custnum) %> +<& /elements/header-popup.html, 'Invoice voided' &> + + %} <%init> diff --git a/httemplate/misc/unvoid-cust_bill_void.html b/httemplate/misc/unvoid-cust_bill_void.html new file mode 100755 index 000000000..f61416549 --- /dev/null +++ b/httemplate/misc/unvoid-cust_bill_void.html @@ -0,0 +1,25 @@ +%if ( $error ) { +% errorpage($error); +%} else { +% my $show = $curuser->default_customer_view =~ /^(jumbo|payment_history)$/ +% ? '' +% : ';show=payment_history'; +<% $cgi->redirect($p. "view/cust_main.cgi?custnum=$custnum$show" ) %> +%} +<%init> + +my $curuser = $FS::CurrentUser::CurrentUser; + +die "access denied" + unless $curuser->access_right('Unvoid invoices'); + +#untaint invnum +$cgi->param('invnum') =~ /^(\d+)$/ || die "Illegal invnum"; +my $invnum = $1; + +my $cust_bill_void = qsearchs('cust_bill_void', { 'invnum' => $invnum } ); +my $custnum = $cust_bill_void->custnum; + +my $error = $cust_bill_void->unvoid; + + diff --git a/httemplate/misc/unvoid-cust_pay_void.cgi b/httemplate/misc/unvoid-cust_pay_void.cgi index 91fe1c223..4726ee576 100755 --- a/httemplate/misc/unvoid-cust_pay_void.cgi +++ b/httemplate/misc/unvoid-cust_pay_void.cgi @@ -6,7 +6,7 @@ <%init> die "access denied" - unless $FS::CurrentUser::CurrentUser->access_right('Unvoid'); + unless $FS::CurrentUser::CurrentUser->access_right('Unvoid payments'); #untaint paynum my($query) = $cgi->keywords; diff --git a/httemplate/misc/void-cust_pay.cgi b/httemplate/misc/void-cust_pay.cgi index 7b484e93e..31b7a6201 100755 --- a/httemplate/misc/void-cust_pay.cgi +++ b/httemplate/misc/void-cust_pay.cgi @@ -12,7 +12,7 @@ my $paynum = $1; my $cust_pay = qsearchs('cust_pay',{'paynum'=>$paynum}); -my $right = 'Regular void'; +my $right = 'Void payments'; $right = 'Credit card void' if $cust_pay->payby eq 'CARD'; $right = 'Echeck void' if $cust_pay->payby eq 'CHEK'; diff --git a/httemplate/view/cust_main/payment_history/payment.html b/httemplate/view/cust_main/payment_history/payment.html index d7322a2d6..ff269bfaf 100644 --- a/httemplate/view/cust_main/payment_history/payment.html +++ b/httemplate/view/cust_main/payment_history/payment.html @@ -181,7 +181,7 @@ $void = areyousure_link("${p}misc/void-cust_pay.cgi?".$cust_pay->paynum, && $curuser->access_right('Echeck void') ) || ( $cust_pay->payby !~ /^(CARD|CHEK)$/ - && $curuser->access_right('Regular void') + && $curuser->access_right('Void payments') ) ) ); diff --git a/httemplate/view/cust_main/payment_history/voided_invoice.html b/httemplate/view/cust_main/payment_history/voided_invoice.html index 7bf206352..15393cbf5 100644 --- a/httemplate/view/cust_main/payment_history/voided_invoice.html +++ b/httemplate/view/cust_main/payment_history/voided_invoice.html @@ -25,7 +25,13 @@ my $link = $curuser->access_right('View invoices') ? qq!! : ''; -my $unvoid = ''; #XXX unvoid +my $unvoid = ''; +$unvoid = areyousure_link("${p}misc/unvoid-cust_bill_void.html?invnum=". $cust_bill_void->invnum, + emt('Are you sure you want to unvoid this invoice?'), + emt('Unvoid this invoice'), + emt('unvoid') + ) + if $cust_bill_void->closed !~ /^Y/ && $curuser->access_right('Unvoid invoices'); my $delete = ''; $delete = areyousure_link("${p}misc/delete-cust_bill.html?$invnum", diff --git a/httemplate/view/cust_main/payment_history/voided_payment.html b/httemplate/view/cust_main/payment_history/voided_payment.html index 2f038be41..88b5e0a84 100644 --- a/httemplate/view/cust_main/payment_history/voided_payment.html +++ b/httemplate/view/cust_main/payment_history/voided_payment.html @@ -31,6 +31,6 @@ $unvoid = areyousure_link("${p}misc/unvoid-cust_pay_void.cgi?".$cust_pay_void->p emt('Unvoid this payment from the database') . $unvoidmsg, emt('unvoid') ) - if ( $cust_pay_void->closed !~ /^Y/i && $curuser->access_right('Unvoid') ); + if ( $cust_pay_void->closed !~ /^Y/i && $curuser->access_right('Unvoid payments') ); -- 2.11.0