X-Git-Url: http://git.freeside.biz/gitweb/?p=freeside.git;a=blobdiff_plain;f=FS%2FFS%2Fcust_pkg.pm;h=456847ea724dced1b0faeefa972ac2da8a5d3832;hp=d15eb89ac97c1141ee7ef902ae3863ecf0e39367;hb=674cb2d9d7105f4cc2871539b2e9f7088cdaa750;hpb=d22baa4e71bfa9e153c1fe1152ff4c748f1d935c diff --git a/FS/FS/cust_pkg.pm b/FS/FS/cust_pkg.pm index d15eb89ac..456847ea7 100644 --- a/FS/FS/cust_pkg.pm +++ b/FS/FS/cust_pkg.pm @@ -1129,6 +1129,135 @@ sub cancel_if_expired { ''; } +=item uncancel_svc_x + +For cancelled cust_pkg, returns a list of new, uninserted FS::svc_X records +for services that would be inserted by L. Returned objects also +include the field '_uncancel_svcnum' that contains the original svcnum. +Set pkgnum before inserting. + +Accepts the following options: + +summarize_size - if true, returns empty list if number of potential services is +equal to or greater than this + +only_svcnum - arrayref of svcnum, only returns objects for these svcnum +(and only if they would otherwise be returned by this) + +=cut + +sub uncancel_svc_x { + my ($self, %opt) = @_; + + die 'uncancel_svc_x called on a non-cancelled cust_pkg' unless $self->get('cancel'); + + #find historical services within this timeframe before the package cancel + # (incompatible with "time" option to cust_pkg->cancel?) + my $fuzz = 2 * 60; #2 minutes? too much? (might catch separate unprovision) + # too little? (unprovisioing export delay?) + my($end, $start) = ( $self->get('cancel'), $self->get('cancel') - $fuzz ); + my @h_cust_svc = $self->h_cust_svc( $end, $start ); + + return () if $opt{'summarize_size'} and @h_cust_svc >= $opt{'summarize_size'}; + + my @svc_x; + foreach my $h_cust_svc (@h_cust_svc) { + next if $opt{'only_svcnum'} && !(grep { $_ == $h_cust_svc->svcnum } @{$opt{'only_svcnum'}}); + my $h_svc_x = $h_cust_svc->h_svc_x( $end, $start ); + #next unless $h_svc_x; #should this happen? + (my $table = $h_svc_x->table) =~ s/^h_//; + require "FS/$table.pm"; + my $class = "FS::$table"; + my $svc_x = $class->new( { + 'svcpart' => $h_cust_svc->svcpart, + '_uncancel_svcnum' => $h_cust_svc->svcnum, + map { $_ => $h_svc_x->get($_) } fields($table) + } ); + + # radius_usergroup + if ( $h_svc_x->isa('FS::h_svc_Radius_Mixin') ) { + $svc_x->usergroup( [ $h_svc_x->h_usergroup($end, $start) ] ); + } + + #these are pretty rare, but should handle them + # - dsl_device (mac addresses) + # - phone_device (mac addresses) + # - dsl_note (ikano notes) + # - domain_record (i.e. restore DNS information w/domains) + # - inventory_item(?) (inventory w/un-cancelling service?) + # - nas (svc_broaband nas stuff) + #this stuff is unused in the wild afaik + # - mailinglistmember + # - router.svcnum? + # - svc_domain.parent_svcnum? + # - acct_snarf (ancient mail fetching config) + # - cgp_rule (communigate) + # - cust_svc_option (used by our Tron stuff) + # - acct_rt_transaction (used by our time worked stuff) + + push @svc_x, $svc_x; + } + return @svc_x; +} + +=item uncancel_svc_summary + +Returns an array of hashrefs, one for each service that could +potentially be reprovisioned by L, with the following keys: + +svcpart + +svc + +uncancel_svcnum + +label + +reprovisionable - 1 if test reprovision succeeded, otherwise 0 + +Cannot be run from within a transaction. Performs inserts +to test the results, and then rolls back the transaction. +Does not perform exports, so does not catch if export would fail. + +Also accepts the following options: + +summarize_size - if true, returns empty list if number of potential services is +equal to or greater than this + +=cut + +sub uncancel_svc_summary { + my ($self, %opt) = @_; + + die 'uncancel_svc_summary called on a non-cancelled cust_pkg' unless $self->get('cancel'); + die 'uncancel_svc_summary called from within a transaction' unless $FS::UID::AutoCommit; + + local $FS::svc_Common::noexport_hack = 1; # very important not to run exports!!! + local $FS::UID::AutoCommit = 0; + + my @out; + foreach my $svc_x ($self->uncancel_svc_x(%opt)) { + $svc_x->pkgnum($self->pkgnum); # provisioning services on a canceled package, will be rolled back + my $part_svc = $svc_x->part_svc; + my $out = { + 'svcpart' => $part_svc->svcpart, + 'svc' => $part_svc->svc, + 'uncancel_svcnum' => $svc_x->get('_uncancel_svcnum'), + }; + if ($svc_x->insert) { # if error inserting + $out->{'label'} = "(cannot re-provision)"; + $out->{'reprovisionable'} = 0; + } else { + $out->{'label'} = $svc_x->label; + $out->{'reprovisionable'} = 1; + } + push @out, $out; + } + + dbh->rollback; + return @out; +} + =item uncancel "Un-cancels" this package: Orders a new package with the same custnum, pkgpart, @@ -1141,6 +1270,8 @@ svc_fatal: service provisioning errors are fatal svc_errors: pass an array reference, will be filled in with any provisioning errors +only_svcnum: arrayref, only attempt to re-provision these cancelled services + main_pkgnum: link the package as a supplemental package of this one. For internal use only. @@ -1197,32 +1328,12 @@ sub uncancel { # insert services ## - #find historical services within this timeframe before the package cancel - # (incompatible with "time" option to cust_pkg->cancel?) - my $fuzz = 2 * 60; #2 minutes? too much? (might catch separate unprovision) - # too little? (unprovisioing export delay?) - my($end, $start) = ( $self->get('cancel'), $self->get('cancel') - $fuzz ); - my @h_cust_svc = $self->h_cust_svc( $end, $start ); - my @svc_errors; - foreach my $h_cust_svc (@h_cust_svc) { - my $h_svc_x = $h_cust_svc->h_svc_x( $end, $start ); - #next unless $h_svc_x; #should this happen? - (my $table = $h_svc_x->table) =~ s/^h_//; - require "FS/$table.pm"; - my $class = "FS::$table"; - my $svc_x = $class->new( { - 'pkgnum' => $cust_pkg->pkgnum, - 'svcpart' => $h_cust_svc->svcpart, - map { $_ => $h_svc_x->get($_) } fields($table) - } ); - - # radius_usergroup - if ( $h_svc_x->isa('FS::h_svc_Radius_Mixin') ) { - $svc_x->usergroup( [ $h_svc_x->h_usergroup($end, $start) ] ); - } + foreach my $svc_x ($self->uncancel_svc_x('only_svcnum' => $options{'only_svcnum'})) { + $svc_x->pkgnum($cust_pkg->pkgnum); my $svc_error = $svc_x->insert; + if ( $svc_error ) { if ( $options{svc_fatal} ) { $dbh->rollback if $oldAutoCommit; @@ -1246,23 +1357,7 @@ sub uncancel { } } # svc_fatal } # svc_error - } #foreach $h_cust_svc - - #these are pretty rare, but should handle them - # - dsl_device (mac addresses) - # - phone_device (mac addresses) - # - dsl_note (ikano notes) - # - domain_record (i.e. restore DNS information w/domains) - # - inventory_item(?) (inventory w/un-cancelling service?) - # - nas (svc_broaband nas stuff) - #this stuff is unused in the wild afaik - # - mailinglistmember - # - router.svcnum? - # - svc_domain.parent_svcnum? - # - acct_snarf (ancient mail fetching config) - # - cgp_rule (communigate) - # - cust_svc_option (used by our Tron stuff) - # - acct_rt_transaction (used by our time worked stuff) + } #foreach uncancel_svc_x ## # also move over any services that didn't unprovision at cancellation