From: Jonathan Prykop Date: Fri, 1 Jul 2016 04:21:17 +0000 (-0500) Subject: RT#17599: display cancelled services from history [display unprovisionable services... X-Git-Url: http://git.freeside.biz/gitweb/?p=freeside.git;a=commitdiff_plain;h=bb174fcb28d7df1673a9c55edc7d953017b5288f RT#17599: display cancelled services from history [display unprovisionable services from history] --- diff --git a/FS/FS/cust_pkg.pm b/FS/FS/cust_pkg.pm index e3fb1558e..4ad963956 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,45 @@ 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 + if ($opt{'no_test_reprovision'} or $svc_x->insert) { + # 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; diff --git a/httemplate/misc/cancel_pkg.html b/httemplate/misc/cancel_pkg.html index c802897bb..d3ca9964f 100755 --- a/httemplate/misc/cancel_pkg.html +++ b/httemplate/misc/cancel_pkg.html @@ -60,12 +60,14 @@ % foreach my $uncancel_svc (@uncancel_svcs) { % my $uncancel_curr_value = $uncancel_svc->{'uncancel_svcnum'}; % my $uncancel_disabled = ''; +% my $uncancel_postfix = ''; % if ($cgi->param('error')) { -% $uncancel_curr_value = '' unless grep { $_ == $uncancel_svc->{'_uncancel_svcnum'} } $cgi->param('only_svcnum'); +% $uncancel_curr_value = '' unless grep { $_ == $uncancel_svc->{'uncancel_svcnum'} } $cgi->param('only_svcnum'); % } % unless ($uncancel_svc->{'reprovisionable'}) { % $uncancel_curr_value = ''; % $uncancel_disabled = 1; +% $uncancel_postfix = '(' . emt('Cannot be reprovisioned') . ')'; % } <& /elements/tr-checkbox.html, 'label' => $uncancel_svc->{'svc'} . ': ' . $uncancel_svc->{'label'}, @@ -73,7 +75,8 @@ 'value' => $uncancel_svc->{'uncancel_svcnum'}, 'curr_value' => $uncancel_curr_value, 'disabled' => $uncancel_disabled, - 'cell_style' => 'font-weight: normal;' + 'cell_style' => 'font-weight: normal', + 'postfix' => $uncancel_postfix, &> % } % } diff --git a/httemplate/view/cust_main/packages/services.html b/httemplate/view/cust_main/packages/services.html index 352f5ea9d..a23a4c2fe 100644 --- a/httemplate/view/cust_main/packages/services.html +++ b/httemplate/view/cust_main/packages/services.html @@ -110,13 +110,16 @@ function clearhint_search_cust_svc(obj, str) { % } #foreach part_svc % if ($cust_pkg->get('cancel')) { -% foreach my $svc (sort { $a->{'svcpart'} <=> $b->{'svcpart'} } -% $cust_pkg->uncancel_svc_summary('summarize_size' => $opt{'cust_pkg-large_pkg_size'}) +% foreach my $svc ( +% $cust_pkg->uncancel_svc_summary('summarize_size' => $opt{'cust_pkg-large_pkg_size'}, 'no_test_reprovision' => 1) % ) { -% next unless $svc->{'reprovisionable'}; <% $svc->{'svc'} |h %> - <% $svc->{'label'} |h %> + + <% $svc->{'num_cust_svc'} + ? $svc->{'num_cust_svc'} . ' ' . emt('services in history') + : (defined($svc->{'label'}) ? $svc->{'label'} : emt('(cannot load svc label)')) |h %> + % } % } diff --git a/httemplate/view/cust_main/packages/status.html b/httemplate/view/cust_main/packages/status.html index 001c12876..97011c3b7 100644 --- a/httemplate/view/cust_main/packages/status.html +++ b/httemplate/view/cust_main/packages/status.html @@ -715,6 +715,8 @@ sub pkg_uncancel_link { 'actionlabel' => emt('Un-cancel'), #'color' => #? 'cust_pkg' => shift, + 'width' => 960, + 'height' => 740, ) }