summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--FS/FS/cust_main.pm87
-rw-r--r--bin/wipe-customers30
-rwxr-xr-xhttemplate/misc/process/delete-customer.cgi2
3 files changed, 96 insertions, 23 deletions
diff --git a/FS/FS/cust_main.pm b/FS/FS/cust_main.pm
index 3bfccfc66..83cb25b3e 100644
--- a/FS/FS/cust_main.pm
+++ b/FS/FS/cust_main.pm
@@ -1301,7 +1301,7 @@ sub reexport {
}
-=item delete NEW_CUSTNUM
+=item delete [ OPTION => VALUE ... ]
This deletes the customer. If there is an error, returns the error, otherwise
returns false.
@@ -1311,18 +1311,20 @@ what you want when a customer cancels service; for that, cancel all of the
customer's packages (see L</cancel>).
If the customer has any uncancelled packages, you need to pass a new (valid)
-customer number for those packages to be transferred to. Cancelled packages
-will be deleted. Did I mention that this is NOT what you want when a customer
-cancels service and that you really should be looking see L<FS::cust_pkg/cancel>?
+customer number for those packages to be transferred to, as the "new_customer"
+option. Cancelled packages will be deleted. Did I mention that this is NOT
+what you want when a customer cancels service and that you really should be
+looking at L<FS::cust_pkg/cancel>?
You can't delete a customer with invoices (see L<FS::cust_bill>),
-or credits (see L<FS::cust_credit>), payments (see L<FS::cust_pay>) or
-refunds (see L<FS::cust_refund>).
+statements (see L<FS::cust_statement>), credits (see L<FS::cust_credit>),
+payments (see L<FS::cust_pay>) or refunds (see L<FS::cust_refund>), unless you
+set the "delete_financials" option to a true value.
=cut
sub delete {
- my $self = shift;
+ my( $self, %opt ) = @_;
local $SIG{HUP} = 'IGNORE';
local $SIG{INT} = 'IGNORE';
@@ -1335,26 +1337,47 @@ sub delete {
local $FS::UID::AutoCommit = 0;
my $dbh = dbh;
- if ( $self->cust_bill ) {
- $dbh->rollback if $oldAutoCommit;
- return "Can't delete a customer with invoices";
+ if ( qsearch('agent', { 'agent_custnum' => $self->custnum } ) ) {
+ $dbh->rollback if $oldAutoCommit;
+ return "Can't delete a master agent customer";
}
- if ( $self->cust_credit ) {
- $dbh->rollback if $oldAutoCommit;
- return "Can't delete a customer with credits";
- }
- if ( $self->cust_pay ) {
- $dbh->rollback if $oldAutoCommit;
- return "Can't delete a customer with payments";
+
+ #use FS::access_user
+ if ( qsearch('access_user', { 'user_custnum' => $self->custnum } ) ) {
+ $dbh->rollback if $oldAutoCommit;
+ return "Can't delete a master employee customer";
}
- if ( $self->cust_refund ) {
- $dbh->rollback if $oldAutoCommit;
- return "Can't delete a customer with refunds";
+
+ tie my %financial_tables, 'Tie::IxHash',
+ 'cust_bill' => 'invoices',
+ 'cust_statement' => 'statements',
+ 'cust_credit' => 'credits',
+ 'cust_pay' => 'payments',
+ 'cust_refund' => 'refunds',
+ ;
+
+ foreach my $table ( keys %financial_tables ) {
+
+ my @records = $self->$table();
+
+ if ( @records && ! $opt{'delete_financials'} ) {
+ $dbh->rollback if $oldAutoCommit;
+ return "Can't delete a customer with ". $financial_tables{$table};
+ }
+
+ foreach my $record ( @records ) {
+ my $error = $record->delete;
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return "Error deleting ". $financial_tables{$table}. ": $error\n";
+ }
+ }
+
}
my @cust_pkg = $self->ncancelled_pkgs;
if ( @cust_pkg ) {
- my $new_custnum = shift;
+ my $new_custnum = $opt{'new_custnum'};
unless ( qsearchs( 'cust_main', { 'custnum' => $new_custnum } ) ) {
$dbh->rollback if $oldAutoCommit;
return "Invalid new customer number: $new_custnum";
@@ -1381,7 +1404,14 @@ sub delete {
}
}
- foreach my $table (qw( cust_main_invoice cust_main_exemption cust_tag )) {
+ #cust_tax_adjustment in financials?
+ #cust_pay_pending? ouch
+ foreach my $table (qw(
+ cust_main_invoice cust_main_exemption cust_tag cust_attachment contact
+ cust_location cust_main_note cust_tax_adjustment
+ cust_pay_void cust_pay_batch queue cust_tax_exempt
+ cust_recon
+ )) {
foreach my $record ( qsearch( $table, { 'custnum' => $self->custnum } ) ) {
my $error = $record->delete;
if ( $error ) {
@@ -1391,6 +1421,19 @@ sub delete {
}
}
+ my $sth = $dbh->prepare(
+ 'UPDATE cust_main SET referral_custnum = NULL WHERE referral_custnum = ?'
+ ) or do {
+ my $errstr = $dbh->errstr;
+ $dbh->rollback if $oldAutoCommit;
+ return $errstr;
+ };
+ $sth->execute($self->custnum) or do {
+ my $errstr = $sth->errstr;
+ $dbh->rollback if $oldAutoCommit;
+ return $errstr;
+ };
+
my $error = $self->SUPER::delete;
if ( $error ) {
$dbh->rollback if $oldAutoCommit;
diff --git a/bin/wipe-customers b/bin/wipe-customers
new file mode 100644
index 000000000..e65ed61be
--- /dev/null
+++ b/bin/wipe-customers
@@ -0,0 +1,30 @@
+#!/usr/bin/perl
+
+use strict;
+use FS::UID qw(adminsuidsetup);
+use FS::Record qw(qsearch);
+use FS::cust_main;
+
+die "this removes all customers in your database except for customer 1 - remove this line to enable";
+
+my $user = shift or die "usage: wipe-customers username\n";
+adminsuidsetup $user;
+
+#this isn't terribly efficient, but the idea was clearing out a test database,
+#not actually destroying a large amount of data
+
+foreach my $cust_main (
+
+ qsearch('cust_main', { 'custnum' => { op=>'!=', value=>'1' } } )
+
+) {
+
+ my @cerrors = $cust_main->cancel( quiet=>1, nobill=>1 );
+ if ( @cerrors ) {
+ die join(' / ', @cerrors);
+ }
+
+ my $error = $cust_main->delete( 'delete_financials' => 1);
+ die $error if $error;
+
+}
diff --git a/httemplate/misc/process/delete-customer.cgi b/httemplate/misc/process/delete-customer.cgi
index d509a5e0e..12011311a 100755
--- a/httemplate/misc/process/delete-customer.cgi
+++ b/httemplate/misc/process/delete-customer.cgi
@@ -28,6 +28,6 @@ if ( $cgi->param('new_custnum') ) {
my $cust_main = qsearchs( 'cust_main', { 'custnum' => $custnum } )
or die "Customer not found: $custnum";
-my $error = $cust_main->delete($new_custnum);
+my $error = $cust_main->delete('new_custnum' => $new_custnum);
</%init>