[freeside-commits] branch master updated. bf79875847923d0f33a2136d703dd7d9fb8c188a

Mark Wells mark at 420.am
Thu Jul 7 20:31:40 PDT 2016


The branch, master has been updated
       via  bf79875847923d0f33a2136d703dd7d9fb8c188a (commit)
       via  66ca614efafe334e2eff37d912f786dd1121548a (commit)
      from  a983ba996fbd3d432443eff8afc4b09bb48ec443 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit bf79875847923d0f33a2136d703dd7d9fb8c188a
Author: Mark Wells <mark at freeside.biz>
Date:   Thu Jul 7 20:22:39 2016 -0700

    when changing a package with scheduled expiration, transfer the expiration reason to the new package, #71623

diff --git a/FS/FS/cust_pkg.pm b/FS/FS/cust_pkg.pm
index 5a96c15..8d16fe0 100644
--- a/FS/FS/cust_pkg.pm
+++ b/FS/FS/cust_pkg.pm
@@ -2529,6 +2529,21 @@ sub change {
       return "transferring package notes: $error";
     }
   }
+
+  # transfer scheduled expire/adjourn reasons
+  foreach my $action ('expire', 'adjourn') {
+    if ( $cust_pkg->get($action) ) {
+      my $reason = $self->last_cust_pkg_reason($action);
+      if ( $reason ) {
+        $reason->set('pkgnum', $cust_pkg->pkgnum);
+        $error = $reason->replace;
+        if ( $error ) {
+          $dbh->rollback if $oldAutoCommit;
+          return "transferring $action reason: $error";
+        }
+      }
+    }
+  }
   
   my @new_supp_pkgs;
 
diff --git a/FS/FS/cust_pkg_reason.pm b/FS/FS/cust_pkg_reason.pm
index d11d05e..29b4b0a 100644
--- a/FS/FS/cust_pkg_reason.pm
+++ b/FS/FS/cust_pkg_reason.pm
@@ -209,6 +209,54 @@ sub _upgrade_data { # class method
     FS::upgrade_journal->set_done('cust_pkg_reason__missing_reason');
   }
 
+  # Fix misplaced expire/suspend reasons due to package change (RT#71623).
+  # These will look like:
+  # - there is an expire reason linked to pkg1
+  # - pkg1 has been canceled before the reason's date
+  # - pkg2 was changed from pkg1, has an expire date equal to the reason's
+  #   date, and has no expire reason (check this later)
+
+  my $error;
+  foreach my $action ('expire', 'adjourn') {
+    # Iterate this, because a package could be scheduled to expire, then
+    # changed several times, and we need to walk the reason forward to the
+    # last one.
+    while(1) {
+      my @reasons = qsearch(
+        {
+          select    => 'cust_pkg_reason.*',
+          table     => 'cust_pkg_reason',
+          addl_from => ' JOIN cust_pkg pkg1 USING (pkgnum)
+                         JOIN cust_pkg pkg2 ON (pkg1.pkgnum = pkg2.change_pkgnum)',
+          hashref   => { 'action' => uc(substr($action, 0, 1)) },
+          extra_sql => " AND pkg1.cancel IS NOT NULL
+                         AND cust_pkg_reason.date > pkg1.cancel
+                         AND pkg2.$action = cust_pkg_reason.date"
+        });
+      last if !@reasons;
+      warn "Checking ".scalar(@reasons)." possible misplaced $action reasons.\n";
+      foreach my $cust_pkg_reason (@reasons) {
+        my $new_pkg = qsearchs('cust_pkg', { change_pkgnum => $cust_pkg_reason->pkgnum });
+        my $new_reason = $new_pkg->last_cust_pkg_reason($action);
+        if ($new_reason and $new_reason->_date == $new_pkg->get($action)) {
+          # the expiration reason has been recreated on the new package, so
+          # just delete the old one
+          warn "Cleaning $action reason from canceled pkg#" .
+               $cust_pkg_reason->pkgnum . "\n";
+          $error = $cust_pkg_reason->delete;
+        } else {
+          # then the old reason needs to be transferred
+          warn "Moving $action reason from canceled pkg#" .
+               $cust_pkg_reason->pkgnum .
+               " to new pkg#" . $new_pkg->pkgnum ."\n";
+          $cust_pkg_reason->set('pkgnum' => $new_pkg->pkgnum);
+          $error = $cust_pkg_reason->replace;
+        }
+        die $error if $error;
+      }
+    }
+  }
+
   #still can't fill in an action?  don't abort the upgrade
   local($ignore_empty_action) = 1;
 

commit 66ca614efafe334e2eff37d912f786dd1121548a
Author: Mark Wells <mark at freeside.biz>
Date:   Thu Jul 7 13:01:09 2016 -0700

    enable cancel_pkgs to expire packages even if the reason is missing, #71623, from #37177

diff --git a/FS/FS/cust_main.pm b/FS/FS/cust_main.pm
index 3fb0a87..c28830d 100644
--- a/FS/FS/cust_main.pm
+++ b/FS/FS/cust_main.pm
@@ -76,6 +76,7 @@ use FS::upgrade_journal;
 use FS::sales;
 use FS::cust_payby;
 use FS::contact;
+use FS::reason;
 
 # 1 is mostly method/subroutine entry and options
 # 2 traces progress of some operations
@@ -2159,7 +2160,11 @@ FS::cust_pkg::cancel() methods.
 
 =item quiet - can be set true to supress email cancellation notices.
 
-=item reason - can be set to a cancellation reason (see L<FS:reason>), either a reasonnum of an existing reason, or passing a hashref will create a new reason.  The hashref should have the following keys: typenum - Reason type (see L<FS::reason_type>, reason - Text of the new reason.
+=item reason - can be set to a cancellation reason (see L<FS:reason>), either a
+reasonnum of an existing reason, or passing a hashref will create a new reason.
+The hashref should have the following keys:
+typenum - Reason type (see L<FS::reason_type>)
+reason - Text of the new reason.
 
 =item cust_pkg_reason - can be an arrayref of L<FS::cust_pkg_reason> objects
 for the individual packages, parallel to the C<cust_pkg> argument. The
@@ -2253,12 +2258,26 @@ sub cancel_pkgs {
   if ($opt{'cust_pkg_reason'}) {
     @cprs = @{ delete $opt{'cust_pkg_reason'} };
   }
+  my $null_reason;
   foreach (@pkgs) {
     my %lopt = %opt;
     if (@cprs) {
       my $cpr = shift @cprs;
-      $lopt{'reason'}        = $cpr->reasonnum;
-      $lopt{'reason_otaker'} = $cpr->otaker;
+      if ( $cpr ) {
+        $lopt{'reason'}        = $cpr->reasonnum;
+        $lopt{'reason_otaker'} = $cpr->otaker;
+      } else {
+        warn "no reason found when canceling package ".$_->pkgnum."\n";
+        # we're not actually required to pass a reason to cust_pkg::cancel,
+        # but if we're getting to this point, something has gone awry.
+        $null_reason ||= FS::reason->new_or_existing(
+          reason  => 'unknown reason',
+          type    => 'Cancel Reason',
+          class   => 'C',
+        );
+        $lopt{'reason'} = $null_reason->reasonnum;
+        $lopt{'reason_otaker'} = $FS::CurrentUser::CurrentUser->username;
+      }
     }
     my $error = $_->cancel(%lopt);
     push @errors, 'pkgnum '.$_->pkgnum.': '.$error if $error;

-----------------------------------------------------------------------

Summary of changes:
 FS/FS/cust_main.pm       |   25 +++++++++++++++++++++---
 FS/FS/cust_pkg.pm        |   15 +++++++++++++++
 FS/FS/cust_pkg_reason.pm |   48 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 85 insertions(+), 3 deletions(-)




More information about the freeside-commits mailing list