From 1b6b6467cc475a4630e051269db83381a8b779ec Mon Sep 17 00:00:00 2001 From: ivan Date: Sun, 4 Oct 2009 02:09:15 +0000 Subject: [PATCH 1/1] delete invoices, RT#4048 --- FS/FS/AccessRight.pm | 17 ++++++ FS/FS/Conf.pm | 9 +++- FS/FS/Setup.pm | 2 +- FS/FS/cust_bill.pm | 60 +++++++++++++++++++++- FS/FS/cust_bill_pkg.pm | 50 ++++++++++++++++-- FS/bin/freeside-addgroup | 2 +- bin/mapsecrets2access_user | 2 +- httemplate/misc/delete-cust_bill.html | 21 ++++++++ httemplate/view/cust_bill.cgi | 37 +++++++++---- .../view/cust_main/payment_history/invoice.html | 16 +++++- 10 files changed, 196 insertions(+), 20 deletions(-) create mode 100644 httemplate/misc/delete-cust_bill.html diff --git a/FS/FS/AccessRight.pm b/FS/FS/AccessRight.pm index 856a5f523..e90687d13 100644 --- a/FS/FS/AccessRight.pm +++ b/FS/FS/AccessRight.pm @@ -139,6 +139,7 @@ assigned to users and/or groups. ### 'View invoices', 'Resend invoices', #NEWNEW + 'Delete invoices', #new, but no need to phase in 'View customer tax exemptions', #yow 'View customer batched payments', #NEW @@ -216,3 +217,19 @@ sub rights { @rights; } +sub default_superuser_rights { + my $class = shift; + my %omit = map { $_=>1 } ( + 'Delete customer', + 'Delete invoices', + 'Delete payment', + 'Delete credit', #? + 'Delete refund', #? + 'Raw SQL', + ); + + no warnings 'uninitialized'; + grep { ! $omit{$_} } $class->rights; +} + +1; diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm index e97dc32ad..6ad3fcb82 100644 --- a/FS/FS/Conf.pm +++ b/FS/FS/Conf.pm @@ -482,7 +482,14 @@ worry that config_items is freeside-specific and icky. { 'key' => 'deletecustomers', 'section' => 'UI', - 'description' => 'Enable customer deletions. Be very careful! Deleting a customer will remove all traces that this customer ever existed! It should probably only be used when auditing a legacy database. Normally, you cancel all of a customers\' packages if they cancel service.', + 'description' => 'Enable customer deletions. Be very careful! Deleting a customer will remove all traces that the customer ever existed! It should probably only be used when auditing a legacy database. Normally, you cancel all of a customers\' packages if they cancel service.', + 'type' => 'checkbox', + }, + + { + 'key' => 'deleteinvoices', + 'section' => 'UI', + 'description' => 'Enable invoices deletions. Be very careful! Deleting an invoice will remove all traces that the invoice ever existed! Normally, you would apply a credit against the invoice instead.', #invoice voiding? 'type' => 'checkbox', }, diff --git a/FS/FS/Setup.pm b/FS/FS/Setup.pm index e6344e4aa..e02abcb0b 100644 --- a/FS/FS/Setup.pm +++ b/FS/FS/Setup.pm @@ -352,7 +352,7 @@ sub populate_access { use FS::AccessRight; use FS::access_right; - foreach my $rightname ( FS::AccessRight->rights ) { + foreach my $rightname ( FS::AccessRight->default_superuser_rights ) { my $access_right = new FS::access_right { 'righttype' => 'FS::access_group', 'rightobjnum' => 1, #$supergroup->groupnum, diff --git a/FS/FS/cust_bill.pm b/FS/FS/cust_bill.pm index 472dc7318..e6d0b0dc3 100644 --- a/FS/FS/cust_bill.pm +++ b/FS/FS/cust_bill.pm @@ -139,7 +139,49 @@ Really, don't use it. sub delete { my $self = shift; return "Can't delete closed invoice" 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 $table (qw( + cust_bill_event + cust_credit_bill + cust_bill_pay + cust_bill_pay + cust_credit_bill + cust_pay_batch + cust_bill_pay_batch + cust_bill_pkg + )) { + + foreach my $linked ( $self->$table() ) { + my $error = $linked->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 @@ -353,6 +395,16 @@ sub cust_pay { #; } +sub cust_pay_batch { + my $self = shift; + qsearch('cust_pay_batch', { 'invnum' => $self->invnum } ); +} + +sub cust_bill_pay_batch { + my $self = shift; + qsearch('cust_bill_pay_batch', { 'invnum' => $self->invnum } ); +} + =item cust_bill_pay Returns all payment applications (see L) for this invoice. @@ -367,6 +419,8 @@ sub cust_bill_pay { =item cust_credited +=item cust_credit_bill + Returns all applied credits (see L) for this invoice. =cut @@ -378,6 +432,10 @@ sub cust_credited { ; } +sub cust_credit_bill { + shift->cust_credited(@_); +} + =item tax Returns the tax amount (see L) for this invoice. diff --git a/FS/FS/cust_bill_pkg.pm b/FS/FS/cust_bill_pkg.pm index b825b305a..89e596dd3 100644 --- a/FS/FS/cust_bill_pkg.pm +++ b/FS/FS/cust_bill_pkg.pm @@ -1,7 +1,7 @@ package FS::cust_bill_pkg; use strict; -use vars qw( @ISA ); +use vars qw( @ISA $DEBUG $me ); use FS::Record qw( qsearch qsearchs dbdef dbh ); use FS::cust_main_Mixin; use FS::cust_pkg; @@ -12,6 +12,9 @@ use FS::cust_credit_bill_pkg; @ISA = qw( FS::cust_main_Mixin FS::Record ); +$DEBUG = 0; +$me = '[FS::cust_bill_pkg]'; + =head1 NAME FS::cust_bill_pkg - Object methods for cust_bill_pkg records @@ -133,13 +136,51 @@ sub insert { =item delete -Currently unimplemented. I don't remove line items because there would then be -no record the items ever existed (which is bad, no?) +Not recommended. =cut sub delete { - return "Can't delete cust_bill_pkg records!"; + 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; + + foreach my $table (qw( + cust_bill_pkg_detail + cust_tax_exempt_pkg + cust_bill_pay_pkg + cust_credit_bill_pkg + )) { + + foreach my $linked ( qsearch($table, { billpkgnum=>$self->billpkgnum }) ) { + my $error = $linked->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 @@ -196,6 +237,7 @@ Returns the package (see L) for this invoice line item. sub cust_pkg { my $self = shift; + warn "$me $self -> cust_pkg" if $DEBUG; qsearchs( 'cust_pkg', { 'pkgnum' => $self->pkgnum } ); } diff --git a/FS/bin/freeside-addgroup b/FS/bin/freeside-addgroup index 7b30f7d95..25c23455a 100755 --- a/FS/bin/freeside-addgroup +++ b/FS/bin/freeside-addgroup @@ -24,7 +24,7 @@ my $error = $access_group->insert; die $error if $error; if ( $opt_s ) { - foreach my $rightname ( FS::AccessRight->rights ) { + foreach my $rightname ( FS::AccessRight->default_superuser_rights ) { my $access_right = new FS::access_right { 'righttype' => 'FS::access_group', 'rightobjnum' => $access_group->groupnum, diff --git a/bin/mapsecrets2access_user b/bin/mapsecrets2access_user index 945f130ef..d632360f5 100755 --- a/bin/mapsecrets2access_user +++ b/bin/mapsecrets2access_user @@ -24,7 +24,7 @@ unless ( $supergroup ) { my $error = $supergroup->insert; die $error if $error; - foreach my $rightname ( FS::AccessRight->rights ) { + foreach my $rightname ( FS::AccessRight->default_superuser_rights ) { my $access_right = new FS::access_right { 'righttype' => 'FS::access_group', 'rightobjnum' => $supergroup->groupnum, diff --git a/httemplate/misc/delete-cust_bill.html b/httemplate/misc/delete-cust_bill.html new file mode 100644 index 000000000..3a642b0e9 --- /dev/null +++ b/httemplate/misc/delete-cust_bill.html @@ -0,0 +1,21 @@ +% if ( $error ) { +% errorpage($error); +% } else { +<% $cgi->redirect($p. "view/cust_main.cgi?". $custnum) %> +% } +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Delete invoices'); + +#untaint invnum +my($query) = $cgi->keywords; +$query =~ /^(\d+)$/ || die "Illegal crednum"; +my $invnum = $1; + +my $cust_bill = qsearchs('cust_bill',{'invnum'=>$invnum}); +my $custnum = $cust_bill->custnum; + +my $error = $cust_bill->delete; + + diff --git a/httemplate/view/cust_bill.cgi b/httemplate/view/cust_bill.cgi index 173d30bf2..fbb2cf94d 100755 --- a/httemplate/view/cust_bill.cgi +++ b/httemplate/view/cust_bill.cgi @@ -2,10 +2,31 @@ "View this customer (#$custnum)" => "${p}view/cust_main.cgi?$custnum", )) %> +% if ( $conf->exists('deleteinvoices') +% && $curuser->access_right('Delete invoices' ) +% ) +% { + + + + Delete this invoice +

+ +% } % if ( $cust_bill->owed > 0 % && scalar( grep $payby{$_}, qw(BILL CASH WEST MCRD) ) -% && $FS::CurrentUser::CurrentUser->access_right('Post payment') +% && $curuser->access_right('Post payment') % ) % { % my $s = 0; @@ -36,8 +57,7 @@ % } - -% if ( $FS::CurrentUser::CurrentUser->access_right('Resend invoices') ) { +% if ( $curuser->access_right('Resend invoices') ) { Re-print this invoice @@ -53,10 +73,9 @@ % } - % if ( $conf->exists('invoice_latex') ) { - View typeset invoice + View typeset invoice PDF

% } % #false laziness with search/cust_bill_event.cgi @@ -127,8 +146,10 @@ <% include('/elements/footer.html') %> <%init> +my $curuser = $FS::CurrentUser::CurrentUser; + die "access denied" - unless $FS::CurrentUser::CurrentUser->access_right('View invoices'); + unless $curuser->access_right('View invoices'); #untaint invnum my($query) = $cgi->keywords; @@ -149,7 +170,7 @@ my $cust_bill = qsearchs({ 'table' => 'cust_bill', 'addl_from' => 'LEFT JOIN cust_main USING ( custnum )', 'hashref' => { 'invnum' => $invnum }, - 'extra_sql' => ' AND '. $FS::CurrentUser::CurrentUser->agentnums_sql, + 'extra_sql' => ' AND '. $curuser->agentnums_sql, }); die "Invoice #$invnum not found!" unless $cust_bill; @@ -160,5 +181,3 @@ my $custnum = $cust_bill->custnum; my $link = $templatename ? "$templatename-$invnum" : $invnum; - - diff --git a/httemplate/view/cust_main/payment_history/invoice.html b/httemplate/view/cust_main/payment_history/invoice.html index 0ccdeb85b..fe62be620 100644 --- a/httemplate/view/cust_main/payment_history/invoice.html +++ b/httemplate/view/cust_main/payment_history/invoice.html @@ -1,9 +1,11 @@ -<% $link %><% $pre %>Invoice #<% $invnum %> -(Balance $ <% $cust_bill->owed %>)<% $post %><% $link ? '' : '' %><% $events %> +<% $link %><% $pre %>Invoice #<% $cust_bill->display_invnum %> +(Balance $ <% $cust_bill->owed %>)<% $post %><% $link ? '' : '' %><% $delete %><% $events %> <%init> my( $cust_bill, %opt ) = @_; +my $conf = new FS::Conf; + my $curuser = $FS::CurrentUser::CurrentUser; my($pre, $post) = ('', ''); @@ -18,6 +20,16 @@ my $link = $curuser->access_right('View invoices') ? qq!! : ''; +my $delete = ''; +if ( $conf->exists('deleteinvoices') + && $curuser->access_right('Delete invoices') ) { + $delete = qq! (delete)!; +} + my $events = ''; -- 2.11.0