summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkhoff <khoff>2004-03-27 01:05:33 +0000
committerkhoff <khoff>2004-03-27 01:05:33 +0000
commit6af03ca1ad3c06aa1e7affb634bb0640b139dd6d (patch)
tree36665aca733db2fb4856385028c074ec6a45a3c5
parent6004e9f3ed07a72f6a4c0f24e326b89acc859a45 (diff)
Cancel services in a particular order to get around certain inter-service dependancies
-rw-r--r--FS/FS/Conf.pm6
-rw-r--r--FS/FS/cust_pkg.pm28
-rw-r--r--FS/FS/svc_acct.pm30
-rw-r--r--FS/FS/svc_domain.pm2
4 files changed, 57 insertions, 9 deletions
diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm
index ecd2a9790..e6a970c97 100644
--- a/FS/FS/Conf.pm
+++ b/FS/FS/Conf.pm
@@ -1171,6 +1171,12 @@ httemplate/docs/config.html
'description' => 'Allow negative charges. Normally not used unless importing data from a legacy system that requires this.',
'type' => 'checkbox',
},
+ {
+ 'key' => 'auto_unset_catchall',
+ 'section' => '',
+ 'description' => 'When canceling a svc_acct that is the email catchall for one or more svc_domains, automatically set their catchall fields to null. If this option is not set, the attempt will simply fail.',
+ 'type' => 'checkbox',
+ },
{
'key' => 'system_usernames',
diff --git a/FS/FS/cust_pkg.pm b/FS/FS/cust_pkg.pm
index d60e95b78..ccd73acc8 100644
--- a/FS/FS/cust_pkg.pm
+++ b/FS/FS/cust_pkg.pm
@@ -1,7 +1,7 @@
package FS::cust_pkg;
use strict;
-use vars qw(@ISA $disable_agentcheck $DEBUG);
+use vars qw(@ISA $disable_agentcheck @SVCDB_CANCEL_SEQ $DEBUG);
use FS::UID qw( getotaker dbh );
use FS::Record qw( qsearch qsearchs );
use FS::Misc qw( send_email );
@@ -29,6 +29,14 @@ $DEBUG = 0;
$disable_agentcheck = 0;
+# The order in which to unprovision services.
+@SVCDB_CANCEL_SEQ = qw( svc_external
+ svc_www
+ svc_forward
+ svc_acct
+ svc_domain
+ svc_broadband );
+
sub _cache {
my $self = shift;
my ( $hashref, $cache ) = @_;
@@ -284,16 +292,22 @@ sub cancel {
local $FS::UID::AutoCommit = 0;
my $dbh = dbh;
+ my %svc;
foreach my $cust_svc (
- qsearch( 'cust_svc', { 'pkgnum' => $self->pkgnum } )
+ qsearch( 'cust_svc', { 'pkgnum' => $self->pkgnum } )
) {
- my $error = $cust_svc->cancel;
+ push @{ $svc{$cust_svc->part_svc->svcdb} }, $cust_svc;
+ }
- if ( $error ) {
- $dbh->rollback if $oldAutoCommit;
- return "Error cancelling cust_svc: $error";
- }
+ foreach my $svcdb (@SVCDB_CANCEL_SEQ) {
+ foreach my $cust_svc (@{ $svc{$svcdb} }) {
+ my $error = $cust_svc->cancel;
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return "Error cancelling cust_svc: $error";
+ }
+ }
}
unless ( $self->getfield('cancel') ) {
diff --git a/FS/FS/svc_acct.pm b/FS/FS/svc_acct.pm
index 4ea52520c..100af6cb6 100644
--- a/FS/FS/svc_acct.pm
+++ b/FS/FS/svc_acct.pm
@@ -674,10 +674,36 @@ sub unsuspend {
=item cancel
-Just returns false (no error) for now.
-
Called by the cancel method of FS::cust_pkg (see L<FS::cust_pkg>).
+If the B<auto_unset_catchall> configuration option is set, this method will
+automatically remove any references to the canceled service in the catchall
+field of svc_domain. This allows packages that contain both a svc_domain and
+its catchall svc_acct to be canceled in one step.
+
+=cut
+
+sub cancel {
+ # Only one thing to do at this level
+ my $self = shift;
+ foreach my $svc_domain (
+ qsearch( 'svc_domain', { catchall => $self->svcnum } ) ) {
+ if($conf->exists('auto_unset_catchall')) {
+ my %hash = $svc_domain->hash;
+ $hash{catchall} = '';
+ my $new = new FS::svc_domain ( \%hash );
+ my $error = $new->replace($svc_domain);
+ return $error if $error;
+ } else {
+ return "cannot unprovision svc_acct #".$self->svcnum.
+ " while assigned as catchall for svc_domain #".$svc_domain->svcnum;
+ }
+ }
+
+ $self->SUPER::cancel;
+}
+
+
=item check
Checks all fields to make sure this is a valid service. If there is an error,
diff --git a/FS/FS/svc_domain.pm b/FS/FS/svc_domain.pm
index c88b3e668..4dd6342c7 100644
--- a/FS/FS/svc_domain.pm
+++ b/FS/FS/svc_domain.pm
@@ -256,6 +256,8 @@ sub replace {
return "Can't change domain - reorder."
if $old->getfield('domain') ne $new->getfield('domain');
+ # Better to do it here than to force the caller to remember that svc_domain is weird.
+ $new->setfield(action => 'M');
my $error = $new->SUPER::replace($old);
return $error if $error;
}