X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2Fcust_pkg.pm;h=661625725850d58c810ef5cc1ecf8eae1923556a;hb=7d38afc8a7175c836721400f3b08f84f1c20ea4f;hp=456847ea724dced1b0faeefa972ac2da8a5d3832;hpb=cd254e04ba204b5d0b4a69b65c392fb175dd1e97;p=freeside.git diff --git a/FS/FS/cust_pkg.pm b/FS/FS/cust_pkg.pm index 456847ea7..661625725 100644 --- a/FS/FS/cust_pkg.pm +++ b/FS/FS/cust_pkg.pm @@ -1133,14 +1133,12 @@ sub cancel_if_expired { 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. +include the field _h_svc_x, which contains the service history object. + 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) @@ -1158,19 +1156,20 @@ sub uncancel_svc_x { 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'}}); + # filter out services that still exist on this package (ie preserved svcs) + # but keep services that have since been provisioned on another package (for informational purposes) + next if qsearchs('cust_svc',{ 'svcnum' => $h_cust_svc->svcnum, 'pkgnum' => $self->pkgnum }); my $h_svc_x = $h_cust_svc->h_svc_x( $end, $start ); - #next unless $h_svc_x; #should this happen? + next unless $h_svc_x; # this probably doesn't happen, but just in case (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, + '_h_svc_x' => $h_svc_x, map { $_ => $h_svc_x->get($_) } fields($table) } ); @@ -1211,18 +1210,22 @@ svc uncancel_svcnum -label +label - from history table if not currently calculable, undefined if it can't be loaded reprovisionable - 1 if test reprovision succeeded, otherwise 0 +num_cust_svc - number of svcs for this svcpart, only if summarizing (see below) + 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 +no_test_reprovision - skip the test inserts (reprovisionable field will not exist) + +summarize_size - if true, returns a single summary record for svcparts with at +least this many svcs, will have key num_cust_svc but not uncancel_svcnum, label or reprovisionable =cut @@ -1235,23 +1238,51 @@ sub uncancel_svc_summary { local $FS::svc_Common::noexport_hack = 1; # very important not to run exports!!! local $FS::UID::AutoCommit = 0; + # sort by svcpart, to check summarize_size + my $uncancel_svc_x = {}; + foreach my $svc_x (sort { $a->{'svcpart'} <=> $b->{'svcpart'} } $self->uncancel_svc_x) { + $uncancel_svc_x->{$svc_x->svcpart} = [] unless $uncancel_svc_x->{$svc_x->svcpart}; + push @{$uncancel_svc_x->{$svc_x->svcpart}}, $svc_x; + } + 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; + foreach my $svcpart (keys %$uncancel_svc_x) { + my @svcpart_svc_x = @{$uncancel_svc_x->{$svcpart}}; + if ($opt{'summarize_size'} && (@svcpart_svc_x >= $opt{'summarize_size'})) { + my $svc_x = $svcpart_svc_x[0]; #grab first one for access to $part_svc + my $part_svc = $svc_x->part_svc; + push @out, { + 'svcpart' => $part_svc->svcpart, + 'svc' => $part_svc->svc, + 'num_cust_svc' => scalar(@svcpart_svc_x), + }; } else { - $out->{'label'} = $svc_x->label; - $out->{'reprovisionable'} = 1; + foreach my $svc_x (@svcpart_svc_x) { + my $part_svc = $svc_x->part_svc; + my $out = { + 'svcpart' => $part_svc->svcpart, + 'svc' => $part_svc->svc, + 'uncancel_svcnum' => $svc_x->get('_h_svc_x')->svcnum, + }; + $svc_x->pkgnum($self->pkgnum); # provisioning services on a canceled package, will be rolled back + my $insert_error; + unless ($opt{'no_test_reprovision'}) { + # avoid possibly fatal errors from missing linked records + eval { $insert_error = $svc_x->insert }; + $insert_error ||= $@; + } + if ($opt{'no_test_reprovision'} or $insert_error) { + # avoid possibly fatal errors from missing linked records + eval { $out->{'label'} = $svc_x->label }; + eval { $out->{'label'} = $svc_x->get('_h_svc_x')->label } unless defined($out->{'label'}); + $out->{'reprovisionable'} = 0 unless $opt{'no_test_reprovision'}; + } else { + $out->{'label'} = $svc_x->label; + $out->{'reprovisionable'} = 1; + } + push @out, $out; + } } - push @out, $out; } dbh->rollback; @@ -1400,14 +1431,15 @@ sub uncancel { =item unexpire -Cancels any pending expiration (sets the expire field to null). +Cancels any pending expiration (sets the expire field to null) +for this package and any supplemental packages. If there is an error, returns the error, otherwise returns false. =cut sub unexpire { - my( $self, %options ) = @_; + my( $self ) = @_; my $error; my $oldAutoCommit = $FS::UID::AutoCommit; @@ -1437,6 +1469,14 @@ sub unexpire { return $error; } + foreach my $supp_pkg ( $self->supplemental_pkgs ) { + $error = $supp_pkg->unexpire; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return "unexpiring supplemental pkg#".$supp_pkg->pkgnum.": $error"; + } + } + $dbh->commit or die $dbh->errstr if $oldAutoCommit; ''; #no errors @@ -2044,14 +2084,15 @@ sub unsuspend { =item unadjourn -Cancels any pending suspension (sets the adjourn field to null). +Cancels any pending suspension (sets the adjourn field to null) +for this package and any supplemental packages. If there is an error, returns the error, otherwise returns false. =cut sub unadjourn { - my( $self, %options ) = @_; + my( $self ) = @_; my $error; my $oldAutoCommit = $FS::UID::AutoCommit; @@ -2088,6 +2129,14 @@ sub unadjourn { return $error; } + foreach my $supp_pkg ( $self->supplemental_pkgs ) { + $error = $supp_pkg->unadjourn; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return "unadjourning supplemental pkg#".$supp_pkg->pkgnum.": $error"; + } + } + $dbh->commit or die $dbh->errstr if $oldAutoCommit; ''; #no errors