[freeside-commits] branch FREESIDE_3_BRANCH updated. db1221a82f407c9ebc782ff03e9cf61115eef8cb

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


The branch, FREESIDE_3_BRANCH has been updated
       via  db1221a82f407c9ebc782ff03e9cf61115eef8cb (commit)
       via  6401184cc06d3a324a230490097289d0d6e7fa91 (commit)
       via  7ba0f3f2442dbb788b3fcd50b8a9f48da80556b1 (commit)
      from  f609fce353fab43501bf8e3823c613562f29e18d (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 db1221a82f407c9ebc782ff03e9cf61115eef8cb
Merge: 6401184 f609fce
Author: Mark Wells <mark at freeside.biz>
Date:   Thu Jul 7 20:22:45 2016 -0700

    Merge branch 'FREESIDE_3_BRANCH' of git.freeside.biz:/home/git/freeside into 3.x


commit 6401184cc06d3a324a230490097289d0d6e7fa91
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 e9feabd..e6374de 100644
--- a/FS/FS/cust_pkg.pm
+++ b/FS/FS/cust_pkg.pm
@@ -2364,6 +2364,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 c29a2f9..98b6b81 100644
--- a/FS/FS/cust_pkg_reason.pm
+++ b/FS/FS/cust_pkg_reason.pm
@@ -216,6 +216,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 7ba0f3f2442dbb788b3fcd50b8a9f48da80556b1
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 1b8e033..e4fc3db 100644
--- a/FS/FS/cust_main.pm
+++ b/FS/FS/cust_main.pm
@@ -75,6 +75,7 @@ use FS::cust_attachment;
 use FS::contact;
 use FS::Locales;
 use FS::upgrade_journal;
+use FS::reason;
 
 # 1 is mostly method/subroutine entry and options
 # 2 traces progress of some operations
@@ -2396,7 +2397,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
@@ -2486,12 +2491,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